自定义view的简单使用
程序员文章站
2022-05-30 20:26:40
...
1.目标:继承textview,重写onDraw(),让view中间有一根线
public class MyTextView extends TextView {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int lastx;
private int lasty;
public MyTextView(Context context) {
super(context);
initdraw();
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initdraw();
}
private void initdraw() {
paint.setColor(Color.RED);
paint.setStrokeWidth(1.5f);
}
public boolean onTouchEvent(MotionEvent event){
int xx = (int) event.getX(); //在控件中的x
int yy = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
lastx = xx;
lasty = yy;
break;
case MotionEvent.ACTION_MOVE:
setText("" + new Random().nextInt(10));
int offsetx = xx - lastx; //得到偏移的距离
int offsety = yy - lasty;
/*//这是第一种方法layout()
layout(getLeft()+offsetx ,
getTop() + offsety,
getRight() + offsetx,
getBottom() + offsety); //在移动过程中,不断重绘位置*/
//第二种方法
offsetLeftAndRight(offsetx);
offsetTopAndBottom(offsety);
//第三种方法(父布局.LayoutParams)如LinearLayout.layoutparams和RelativeLayout.layoutparams
// 或者是ViewGroup.MarginLayoutParams
/*ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
params.leftMargin = getLeft() + offsetx;
params.topMargin = getTop() + offsety;
setLayoutParams(params);*/
/*//(父布局.LayoutParams)
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetx;
layoutParams.topMargin = getTop() + offsety;
setLayoutParams(layoutParams);*/
//第4中方法scrollby(或者scrollto)这个是移动手机屏幕观看不动的画布,所以要相反移动
//这种方法是瞬间的。体验并不好,除非用scroller来过度
//((View)getParent()).scrollBy(-offsetx , -offsety);
//第5中方法,scroller配合view的comeputeScroll()
//实现向右移动,代码在上
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawLine(width/2 , 0 , width/2 , height , paint);
}
}
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.liuyan.tview1.MyTextView
android:id="@+id/t1t1"
android:text="123456"
android:background="#a9289b38"
android:layout_width="50dp"
android:layout_height="50dp"/>
</LinearLayout>
2.目标:继承view
public class RectView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mcolor = Color.RED;
public RectView(Context context) {
super(context);
initdraw();
}
public RectView(Context context, AttributeSet attrs) {
super(context, attrs);
//如果有自定义的属性要用到,需加入下列代码:
TypedArray typearray = context.obtainStyledAttributes(attrs , R.styleable.RectView);
mcolor = typearray.getColor(R.styleable.RectView_rect_color , Color.RED);//没有设置该属性,默认为第2参数
typearray.recycle();//获取资源必须及时回收
initdraw();
}
private void initdraw() {
paint.setColor(mcolor);
paint.setStrokeWidth(1.5f);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas); //默认的不计算padding
/*//没有对padding做出改变,padding属性无效
int width = getWidth();
int height = getHeight();
canvas.drawRect(0 , 0 , width , height , paint);*/
//设置对layoutpadding的改变
int paddingleft = getPaddingLeft();
int paddingright = getPaddingRight();
int paddingtop = getPaddingTop();
int paddingbottom = getPaddingBottom();
int width = getWidth() - paddingleft - paddingright;
int height = getHeight() - paddingtop - paddingbottom;
canvas.drawRect(paddingleft , paddingtop , paddingleft+width , paddingtop+height , paint);
}
//如果不对specMode分别处理,则wrap_content和match_parent的效果是一样的
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthspecmode = MeasureSpec.getMode(widthMeasureSpec);
int widthspecsize = MeasureSpec.getSize(widthMeasureSpec);
int heightspecmode = MeasureSpec.getMode(heightMeasureSpec);
int heightspecsize = MeasureSpec.getSize(heightMeasureSpec);
if (widthspecmode == MeasureSpec.AT_MOST && heightspecmode == MeasureSpec.AT_MOST){
//如果宽度和高度都是用了wrap_content
setMeasuredDimension(400 , 400);//默认的为setMeasureDimension(getDefaultSiza(getSuggestedMinimumWidth() , height一样写法)
} else if (widthspecmode == MeasureSpec.AT_MOST){
//只有宽度为wrap_content
setMeasuredDimension(400 , heightspecsize);
} else if (heightspecmode == MeasureSpec.AT_MOST){
setMeasuredDimension(widthspecsize , 400);
}
}
}
自定义属性在values/attrs.xml中
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RectView"> <attr name="rect_color" format="color"/> </declare-styleable> </resources>
layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.liuyan.tview1.RectView xmlns:app="http://schemas.android.com/apk/res-auto" android:background="#8961bd57" android:layout_width="wrap_content" android:layout_height="200dp" android:padding="50dp" app:rect_color="#a7c7ac13" /> </LinearLayout>
上一篇: 最简单的自定义View