public final void measure(int widthMeasureSpec, int heightMeasureSpec) protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)measure调用onMeasure,onMeasure测量宽度、高度然后调用setMeasureDimension保存测量结果,measure,setMeasureDimension是final类型,view的子类不需要重写,onMeasure在view的子类中重写。
public void layout(int l, int t, int r, int b)protected boolean setFrame(int left, int top, int right, int bottom)protected void onLayout(boolean changed, int left, int top, int right, int bottom)layout通过调用setFrame(l,t,r,b),l,t,r,b即子视图在父视图中的具体位置,onLayout一般只会在自定义ViewGroup中才会使用
public void draw(Canvas canvas)protected void onDraw(Canvas canvas)通过调用draw函数进行视图绘制,在View类中onDraw函数是个空函数,最终的绘制需求需要在自定义的onDraw函数中进行实现,比如ImageView完成图片的绘制,如果自定义ViewGroup这个函数则不需要重载。
public class PercentView extends View {private final static String TAG = PercentView.class.getSimpleName();private Paint mPaint;public PercentView(Context context) {super(context);}public PercentView(Context context, AttributeSet attrs) {super(context, attrs);}public PercentView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);Log.e(TAG, "onMeasure--widthMode-->" + widthMode);switch (widthMode) {case MeasureSpec.EXACTLY:break;case MeasureSpec.AT_MOST:break;case MeasureSpec.UNSPECIFIED:break;}Log.e(TAG, "onMeasure--widthSize-->" + widthSize);Log.e(TAG, "onMeasure--heightMode-->" + heightMode);Log.e(TAG, "onMeasure--heightSize-->" + heightSize);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);Log.e(TAG, "onLayout");}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(Color.GRAY);// FILL填充, STROKE描边,FILL_AND_STROKE填充和描边mPaint.setStyle(Paint.Style.FILL_AND_STROKE);int with = getWidth();int height = getHeight();Log.e(TAG, "onDraw---->" + with + "*" + height);float radius = with / 4;canvas.drawCircle(with / 2, with / 2, radius, mPaint);mPaint.setColor(Color.BLUE);RectF oval = new RectF(with / 2 - radius, with / 2 - radius, with / 2+ radius, with / 2 + radius); //用于定义的圆弧的形状和大小的界限canvas.drawArc(oval, 270, 120, true, mPaint); //根据进度画圆弧}}在布局中如何使用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.whoislcj.views.PercentViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp" /></LinearLayout>显示效果:
如果布局文件改成
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.whoislcj.views.PercentViewandroid:layout_width="150dp"android:layout_height="150dp"android:layout_margin="10dp" /></LinearLayout>显示效果变成
总结:
本篇主要介绍Android自定义控件的基本绘制原理,会在下一篇中介绍如何自定义属性。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!