1. 继承View重写onDraw方法
public class CircleView extends View {
private int mColor = Color.RED;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(getResources().getColor(android.R.color.holo_blue_bright));
mPaint.setColor(mColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
int radius = Math.min(width, height) / 2;
canvas.drawCircle(width / 2, height / 2, radius, mPaint);
}
}
2. 问题 padding和wrap_content无效
<qingfengmy.developmentofart._4view.CircleView
android:layout_width="wrap_content"
android:padding="20dp"
android:layout_margin="20dp"
android:layout_height="100dp" />
如上设置时,margin是有效的,因为margin在父View中处理;padding无效,因为继承自View和ViewGroup的控件,padding是需要自己处理的;wrap_content是无效的,前文分析过,在onMeasure的时候,最大模式和精确模式,测量宽高都是设置的父Veiw的剩余空间,wrap_content需要自己处理。
3. wrap_contnet的解决
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
int widthResult = widthSpecSize;
int heightResult = heightSpecSize;
if (widthSpecMode == MeasureSpec.AT_MOST) {
widthResult = mWidth;
}
if (heightSpecMode == MeasureSpec.AT_MOST) {
heightResult = mWidth;
}
setMeasuredDimension(widthResult, heightResult);
}
4. padding的解决
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int width = getWidth() - paddingLeft - paddingRight;
int height = getHeight() - paddingTop - paddingBottom;
int radius = Math.min(width, height) / 2;
canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2, radius, mPaint);
}