前言:最近这段时间想根据网上博客的案例,自己练习自定义View,代码仅仅作为练习用,还有很多不足之处,见谅
案例取自:http://blog.csdn.net/wingichoy/article/details/50460213
自定义View代码:
public class PracticeView2 extends View {
private Paint mPaint = new Paint();
private Path mpath = new Path();
private int mCount = 10;
private int mwidth = 180;
private int mheight = 200;
private float msize = 0;
private int mode;
private int mColor;
public PracticeView2(Context context) {
this(context, null);
}
public PracticeView2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PracticeView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.view2, defStyleAttr, 0);
mColor = array.getColor(R.styleable.view2_color, Color.BLUE);
//mColor = Color.BLUE;
mPaint.setColor(mColor);
mode = array.getInteger(R.styleable.view2_mode, 2);
array.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int mwidthmode = MeasureSpec.getMode(widthMeasureSpec);
int mwidthsize = MeasureSpec.getSize(widthMeasureSpec);
int mheightmode = MeasureSpec.getMode(heightMeasureSpec);
int mheightsize = MeasureSpec.getSize(heightMeasureSpec);
mwidth = mwidthsize;
mheight = mheightsize;
if (mwidthmode == MeasureSpec.AT_MOST) {
mwidth = 180;
}
if (mheightmode == MeasureSpec.AT_MOST) {
mheight = 250;
}
setMeasuredDimension(mwidth, mheight);
Log.d("SunJ", "宽度:" + mwidth + " 高度:" + mheight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
if (mode == 1) {
msize = mheight/(2f*mCount);
Log.d("SunJ", "边长:" + msize);
canvas.drawRect(msize, 0, mwidth-msize, mheight, mPaint);
for(int i=0; i<mCount; i++) {
mpath.moveTo(msize, i*2*msize);
mpath.lineTo(msize, i*2*msize+2*msize);
mpath.lineTo(0, msize+i*2*msize);
mpath.close();
canvas.drawPath(mpath, mPaint);
}
for(int i=0; i<mCount; i++) {
mpath.moveTo(mwidth-msize, i*2*msize);
mpath.lineTo(mwidth-msize, i*2*msize+2*msize);
mpath.lineTo(mwidth, msize+i*2*msize);
mpath.close();
canvas.drawPath(mpath, mPaint);
}
} else if(mode == 2) {
msize = mheight/(2f*mCount);
Log.d("SunJ", "半径:" + msize);
canvas.drawRect(msize, 0, mwidth-msize, mheight, mPaint);
for(int i=0; i<mCount; i++) {
canvas.drawCircle(msize, msize+i*2*msize, msize, mPaint);
canvas.drawCircle(mwidth-msize, msize+i*2*msize, msize, mPaint);
}
}
}
}
activity的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res/com.sunjing.myapplication"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sunjing.myapplication.MainActivity">
<com.sunjing.myapplication.PracticeView2
android:id="@+id/practiceview21"
android:layout_marginLeft="100dp"
android:layout_marginTop="100dp"
android:layout_width="100dp"
android:layout_height="200dp"
custom:mode="mode2"
custom:color="#678edd"/>
<com.sunjing.myapplication.PracticeView2
android:id="@+id/practiceview22"
android:layout_marginLeft="250dp"
android:layout_marginTop="100dp"
android:layout_width="100dp"
android:layout_height="200dp"
custom:mode="mode1"
custom:color="#ef8edd"/>
</RelativeLayout>
自定义属性xml文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="view2">
<attr name="color" format="color" />
<attr name="mode" format="integer">
<enum name="mode1" value="1"/>
<enum name="mode2" value="2"/>
</attr>
</declare-styleable>
</resources>
显示:
最后,做总结:
1.重写View的四大步骤:
①自定义View属性
②在View的构造方法中获得自定义的View属性
③重写onMeasure()方法
④重写onDraw()方法