自定義視圖

View顯示流程

1、onMeasure()測量寬高
2、ViewGroup 佈局, onLayout()
3 、 draw() 視圖顯示自身的內容

1 、繪製背景
2 、爲顯示漸變框做一些準備動作
3 、調用自身的 onDraw(),(ViewGroup 不需要 )
4 、 dispatchDraw() 繪製子視圖 ( 調用了 drawChild() 通知孩子 draw() 自身 )
5 、畫滾動條

View 的自定義的認識

要自定義 View 的顯示效果,可以重寫其 onDraw 方法,然後在 Canvas 上繪製內容即可

public class MyView extends View {
    public MyView(Context context) {
        super(context);
        Log.e("m_tag","MyView(Context context)");
        init();
    }
    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        Log.e("m_tag","MyView(Context context, AttributeSet attrs)");
        init();
    }
    private Paint paint;
    private void init(){
        setBackgroundColor(0xff999999);
        // 創建畫筆對象
        paint = new Paint();
        // 設置畫筆的顏色
        // paint.setColor(0xFFFF0000);
        paint.setColor(Color.RED);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 畫圖 : 畫布 畫筆 顏色
        canvas.drawRect(50,100,150,200,paint);
    }
}

使用:

<com.xykj.viewdemo.MyView
    android:layout_width="match_parent"
    android:layout_height="300dp" />

Canvas的基本繪製

// 畫矩形
// 前面 4 個參數表示矩形的左上右下,第五個參數表示畫筆
canvas.drawRect(50,100,150,200,paint);
// 創建一個矩形對象
Rect rect = new Rect(150,300,350,400);
canvas.drawRect(rect,paint);
// 畫一個圓
//( 圓心 x 座標,圓心 y 座標,半徑,畫筆 )
canvas.drawCircle(50,300,50,paint);

Paint的基本設置

設置顏色
paint.setColor(0xFFFF0000);
paint.setColor(Color.RED); // 從 Color 類中獲取的顏色值
// 消除鋸齒
paint.setAntiAlias(true);
// 分開設置各個顏色參數 0x00-0xff  十進制就是 0-255
paint.setARGB(255,20,50,100);
paint.setAlpha(100); // 設置透明度
// 設置畫筆樣式 STROKE 表示空心 FILL 表示實心
paint.setStyle(Paint.Style.STROKE);
// 空心邊框寬度
paint.setStrokeWidth(5);

View的刷新

如果要修改視圖顯示的內容,需要讓視圖重新 onDraw ,然後在畫布上畫上新的內容即可,要讓視圖重新畫需要使用其刷新方法
主線程刷新:invalidate() ; –> 使視圖重新繪製
結合觸摸監聽實現刷新

public class RefreshView extends View {
    public RefreshView(Context context) {
        super(context);
        init();
    }
    public RefreshView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private Paint paint;
    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
    }
    // 圓的圓心
    private int cx = 50, cy = 100;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 畫圓
        canvas.drawCircle(cx, cy, 50, paint);
    }
    // 視圖的觸摸監聽
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 獲取觸摸的行爲
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 手指觸摸到視圖的瞬間
                // 得到觸控點跟視圖左上角點的座標 ( 相對位置 )
                int x = (int) event.getX();
                // int pX = event.getRawX(); // 得到觸控點和屏幕左上角的位置
                int y = (int) event.getY();
                cx = x;
                cy = y;
                invalidate(); // 刷新視圖 ( 視圖會重新繪製 )
                break;
            case MotionEvent.ACTION_MOVE:
            // 按下之後離開之前的整個過程 ( 重複執行 )
                cx = (int) event.getX();
                cy = (int) event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                // 手指離開視圖的瞬間
                break;
        }
        return true;
    }
}

子線程刷新,需要使用 postInvalidate 方法,該方法等效於 Handler+invalidate 方式

private Thread changeThread;
// 隨機數 ( 產生 0-255 之間的數字 )
private Random r = new Random();
public void startChangeColor() {
    if (null != changeThread && changeThread.isAlive()) {
        return;
    }
    changeThread = new Thread() {
        @Override
        public void run() {
            try {
                while(true) {
                    Thread.sleep(500);
                    // 改變畫筆顏色
                    paint.setARGB(255,r.nextInt(256),r.nextInt(256),r.nextInt(256));
                    // 刷新視圖 ( 子線程 )
                    postInvalidate(); // 等效於 Handler+invalidate
                }
            } catch (InterruptedException e) {
            e.printStackTrace();
            }
        }
    };
    changeThread.start();
}

canvas其他的各種畫

// 圓角矩形
RectF rectF = new RectF(300,10,400,80);
//( 矩形區域,圓角 x 方向半徑,圓角 y 方向半徑 )
canvas.drawRoundRect(rectF,20,20,paint);
// 畫橢圓
RectF oval = new RectF(300,100,400,300);
canvas.drawOval(oval,paint);
RectF arcRectF = new RectF(450,10,550,110);
// 畫弧線或者扇形
// 第一個參數 : 扇形所在的圓所在的矩形區域
// 第二個參數:起始角度
// 第三個參數:跨越的總度數
// 第四個參數: true 表示扇形, false 表示弧線
// 第五個參數:畫筆
canvas.drawArc(arcRectF,-90,90,false,paint);
Path p = new Path();
// 指定起始點
p.moveTo(450,100);
// 畫直線到下一個點
p.lineTo(600,200);
p.lineTo(500,400);
// 畫貝塞爾曲線
// 前面兩個表示弧度控制點,後面兩個參數表示弧線的終點
p.quadTo(300,300,500,200);
// 將最後一個點連接到起始點上
p.close();
// 畫路徑
canvas.drawPath(p,paint)
發佈了27 篇原創文章 · 獲贊 7 · 訪問量 7656
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章