一、自定義View基礎
1、View的繪製流程
在了解自定義View之前,我們需要了解Android中View的繪製流程。View的繪製流程主要包括:
(1)測量(onMeasure):測量一個View的寬高,系統會根據這個寬高來確定View的布局位置。
(2)布局(onLayout):ViewGroup需要布局每個子View的位置,布局完成之後子View才可以被繪製。
(3)繪製(onDraw):如果這個View需要被繪製,那麼系統就會調用onDraw方法,進行繪製。在繪製之前,系統會調用onMeasure和onLayout等方法來確定View的位置和大小。
2、繼承View的自定義View
在使用自定義View之前,我們需要了解如何繼承View類。以下是一個自定義View繼承View類的示例代碼:
public class MyView extends View { public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
二、自定義View的屬性
1、自定義View屬性的定義
Android中使用自定義屬性可以在XML文件中設置一些屬性值,可以讓我們的View更加靈活。以下是一個自定義屬性值的示例:
<declare-styleable name="MyView"> <attr name="my_text" format="string"/> </declare-styleable>
2、在XML文件中使用自定義屬性
以下是一個在XML文件中使用自定義屬性的示例:
3、在自定義View中獲取屬性值
在自定義View中獲取自定義屬性的值可以通過context.getTheme().obtainStyledAttributes方法獲取。以下是一個在自定義View中獲取屬性值的示例:
public class MyView extends View { private String mMyText; public MyView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.MyView, 0, 0); try { mMyText = a.getString(R.styleable.MyView_my_text); } finally { a.recycle(); } } }
三、自定義View的繪製
1、繪製基本圖形
在自定義View中,我們可以使用Canvas對象繪製基本的圖形,如:線條、矩形、圓形等。以下是一個繪製圓形的示例代碼:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawCircle(100, 100, 50, paint); }
2、使用Path繪製複雜圖形
如果需要繪製複雜的圖形,除了基本形狀外,我們可以使用Path對象進行繪製。Path的常用方法有:moveTo、lineTo、quadTo、cubicTo等,可以繪製出各種形狀。以下是一個使用Path繪製心形的示例代碼:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.RED); Path path = new Path(); path.moveTo(150, 150); path.quadTo(200, 100, 250, 150); path.quadTo(200, 200, 150, 250); path.quadTo(100, 200, 150, 150); canvas.drawPath(path, paint); }
四、自定義View的動畫
在自定義View中,我們可以使用屬性動畫進行動畫效果的實現。以下是一個使用屬性動畫實現位移效果的示例代碼:
public class MyView extends View { private int mTranslationX = 0; public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void startAnimate() { ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1000); valueAnimator.setDuration(1000); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mTranslationX = (int) animation.getAnimatedValue(); invalidate(); } }); valueAnimator.start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawRect(mTranslationX, 0, mTranslationX + getWidth(), getHeight(), paint); } }
五、自定義View的觸摸事件
在自定義View中,我們可以使用觸摸事件來實現交互效果。以下是一個處理觸摸事件的示例代碼:
public class MyView extends View { private Paint mPaint; private float mX, mY; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(5); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.RED); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: mX = event.getX(); mY = event.getY(); break; case MotionEvent.ACTION_MOVE: float x = event.getX(); float y = event.getY(); Path path = new Path(); path.moveTo(mX, mY); path.lineTo(x, y); mX = x; mY = y; Canvas canvas = new Canvas(); canvas.drawPath(path, mPaint); break; } return true; } }
原創文章,作者:AFPYB,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/366208.html