自定义视图

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)

猜你喜欢

转载自blog.csdn.net/weixin_42097095/article/details/80699332