实现一个圆形的view
public class CircleView extends View {
private int mColor = Color.WHITE;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//画笔,抗锯齿。
public CircleView(Context context) {
super(context);
setColor(mColor);
}
public CircleView(Context context, @Nullable AttributeSet attrs) {
this(context,attrs,0);
}
public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//加载自定义属性集合
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
//解析CircleView中的circle_color这个属性,若未定义该属性,默认为白色
mColor = array.getColor(R.styleable.CircleView_circle_color,Color.RED);
Log.d("onCreateView","color:"+mColor);
array.recycle();
setColor(mColor);
}
//设置画笔颜色
void setColor(int color){
paint.setColor(color);
}
//使wrap_content生效,当宽高为wrap_content时,值为200dp
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heigthSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heigthSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//如果widthSpecMode和heigthSpecMode均为AT_MOST(宽高均为wrap_content)
//则宽高的值均为200dp
if(widthSpecMode==MeasureSpec.AT_MOST&&heigthSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(200,200);
}
//只有宽为wrap_content
else if(widthSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(200,heigthSpecSize);
}
//只有高为wrap_content
else if(heigthSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(widthSpecSize,200);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//使padding属性可生效
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int paddingTop = getPaddingTop();
final int paddingBottom = getPaddingBottom();
int mWidth = getWidth()-paddingLeft-paddingRight;
int mHeigth = getHeight()-paddingTop-paddingBottom;
int radius = Math.min(mWidth,mHeigth)/2;
//加上多减去的一个padding
canvas.drawCircle(paddingLeft+mWidth/2,paddingTop+mHeigth/2,radius,paint);
}
}
1、首先定义一个CircleView类,继承自View,实现三个构造方法
2、定义了两个paint和color两个变量,paint用于绘制出圆,color用于指定圆的颜色
3、方法setColor(int color)用于在使用构造方法定义该view或需要改变view颜色时设置颜色。
4、重写onMeasure()方法,当widthSpecMode和heightSpecMode的值为AT_MOST时,认为width和height属性值均为wrap_content,并定义warp_content时,width和height默认值为200dp
5、重写onDraw()方法,获取padding,通过计算,可是的padding属性生效(若缺少这一步,就算在layout文件中设置padding属性,也不会生效)
6、自定义属性:在value中新建资源attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleView">
<attr name="circle_color" format="color"/>
</declare-styleable>
</resources>
然后在CircleView第三个构造方法里面加入代码,注意第二个构造方法的内容。
//加载自定义属性集合
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
//解析CircleView中的circle_color这个属性,若未定义该属性,默认为白色
mColor = array.getColor(R.styleable.CircleView_circle_color,Color.RED);
Log.d("onCreateView","color:"+mColor);
array.recycle();
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#ffffff"
android:orientation="vertical">
<com.bing.demo.CircleView
app:circle_color="@color/colorAccent"
android:clickable="true"
android:id="@+id/circle"
android:background="#000000"
android:padding="10dp"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="150dp"/>
</LinearLayout>