Android自定义View的使用(基础篇)

Android自定义View的使用(基础篇)前言 本文主要讲述自定义 View 中 Paint Canvas 以及 Path 的使用 不牵扯到 PathMeasure 和 Matrix 提供画一些常见的点 线 面 矩形 圆 椭圆以及不规则图形

大家好,欢迎来到IT知识分享网。

前言:
    本文主要讲述自定义View中Paint、Canvas以及Path的使用,不牵扯到PathMeasure和Matrix,提供画一些常见的点、线、面、矩形、圆、椭圆以及不规则图形。
    另外需注意:Android的坐标系和数学中的坐标系是有区别的,Android的坐标系是以屏幕的左上角为坐标原点,垂直向下是Y轴的正方向,切勿和数学坐标系混淆。
    先上图形:

Android自定义View的使用(基础篇)

一、自定义View常用方法
    1.构造方法
        自定义View的构造方法有四种,分别是一参二参三参四参,三参四参很少用,主要讲解下一参和二参的区别;
        一参:在code中初始化自定义View的时候调用较多;
        二参:在xml中使用自定义View时会调用;
    2.onDraw:提供画布(Canvas),用来画界面
    3.onMeasure:测量屏幕尺寸,常用方法是getSize和getMode,例(获取屏幕宽度):MeasureSpec.getSize(widthMeasureSpec);
    4.onSizeChanged:在View size发生变化时调用,可以获取old view的size和更新后view的size
    
二、Paint的使用
    1.初始化
        paint = new Paint();
        paint.setColor(Color.RED);//设置颜色
        paint.setStyle(Paint.Style.FILL);//设置paint的类型(包含FILL、STROKE和FILL_AND_STROKE三种)
        paint.setStrokeWidth(10F);//设置线宽
    2.画常见图形
        //点
        canvas.drawPoint(50, 100, paint);
        //一组点
        canvas.drawPoints(new float[]{

                100, 100,
                150, 100,
                200, 100
        }, paint);
        //线
        canvas.drawLine(250, 100, 300, 100, paint);
        //矩形
        canvas.drawRect(new Rect(350, 50, 500, 150), paint);
        //圆角矩形
        canvas.drawRoundRect(new RectF(550, 50, 700, 150), 5, 5, paint);
        //椭圆
        canvas.drawOval(new RectF(750, 50, 900, 150), paint);
        //圆
        canvas.drawCircle(1000, 100, 50, paint);
        //圆弧
        canvas.drawArc(new RectF(1100, 50, 1200, 150), 180, 90, true, paint);
        //空心圆
        paint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(100, 250, 50, paint);
        //饼状图
        paint.setStyle(Paint.Style.FILL);
        RectF rectF = new RectF(250, 200, 350, 300);
        canvas.drawArc(rectF, 0, 60, true, paint);
        paint.setColor(Color.GRAY);
        canvas.drawArc(rectF, 60, 150, true, paint);
        paint.setColor(Color.GREEN);
        canvas.drawArc(rectF, 210, 90, true, paint);
        paint.setColor(Color.YELLOW);
        canvas.drawArc(rectF, 300, 60, true, paint);
        //图片
        //canvas.drawPicture();
        //canvas.drawBitmap();
        //文字
        //canvas.drawText();
    3.实例
        通过以上方法,基本可以满足一些规则图形的需求,例如扇形图表、折线图等,另外也可结合Handler的使用通过invalidate()方法实现动态的效果;
        如下就是简单实现圆柱注水效果的code:
        //画动态水柱
        canvas.drawRoundRect(new RectF(100, 600, 200, 1000), 50, 50, paint);
        paint.setColor(Color.GREEN);
        //下
        canvas.drawArc(new RectF(110, 900, 190, 990), 90 – waterAngle, 2 * waterAngle, false, paint);
        //中
        canvas.drawRect(new RectF(110, waterHeight, 190, 950), paint);
        //上
        if (waterAngle02 == 0) {

            canvas.drawArc(new RectF(110, 610, 190, 700), -waterAngle02, 0, false, paint);
        } else {

            canvas.drawArc(new RectF(110, 610, 190, 700), -waterAngle02, (2 * waterAngle02) + 180, false, paint);
        }

        if (waterAngle < 90) {

            mHandler.sendEmptyMessage(2);//画下半圆
        } else {

            if (waterHeight > 650) {

                mHandler.sendEmptyMessage(1);//画中间
            } else if (waterAngle02 < 90) {

                Log.e(“MyView”, “waterAngle02:” + waterAngle02);
                mHandler.sendEmptyMessage(3);//画上半圆
            }
        }
        
        //动态水柱
        private float waterAngle = 0;
        private float waterAngle02 = 0;
        private int waterHeight = 950;
        private Handler mHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                super.handleMessage(msg);
                if (msg.what == 1) {

                    if (waterHeight > 645) {

                        waterHeight–;
                        mHandler.sendEmptyMessageDelayed(1, 2000);
                        invalidate();
                    }
                } else if (msg.what == 2) {

                    if (waterAngle < 90) {

                        waterAngle++;
                        mHandler.sendEmptyMessageDelayed(2, 2000);
                        invalidate();
                    }
                } else if (msg.what == 3) {

                    if (waterAngle02 < 90) {

                        waterAngle02++;
                        mHandler.sendEmptyMessageDelayed(2, 2000);
                        invalidate();
                    }
                }
            }
        };

三、Canvas的使用
    画布的使用主要为了更加快捷的确定坐标系的位置,类比我们现实中的画板,如果你想画出来一个倒在地上的金字塔,不如在作画前先将画板向右旋转90度,然后画一个正常的金字塔,完成作品后,再将画纸向左旋转回来,就能达到想要的效果。以下介绍几种画布常见的操作方法:
    1.平移:canvas.translate(150, 0);//将画布向右平移150
    2.旋转:canvas.rotate(30, 100, 100);//将画布围绕点(100, 100)旋转30度
    3.缩放:canvas.scale(2f, 2f, 100, 100);//将画布以点(100, 100)放大两倍
    
四、Path的使用
    canvas除了有draw点draw线draw矩形等方法,还可以drawPath(Path path, Paint paint);
    虽然都是要paint来画,但是drawPath不同的是可以画很多不规则图形,形状取决于path;
    1.首先path也可以画规则图形,方法基本类似canvas中画基本图形的方法
    2.特别介绍path中不同于canvas画基本图形的几个方法
        path.lineTo():在路径上添加一个点
        path.moveTo():移动到下次lineTo的起点
        path.setLastPoint():设置上次操作的最后一个点的位置
        path.close():封闭路径
        path.quadTo():用来画贝塞尔曲线(大部分复杂的自定义View都会用到贝塞尔曲线)
    3.简单的贝塞尔曲线的使用
        为了实现根据touch点来绘制指定的贝塞尔曲线:
    public class BezierView extends View {

    private Paint mPaint;
    private int centerX, centerY;
    private PointF start, end, control;

        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.STROKE);

        start = new PointF(0, 0);
        end = new PointF(0, 0);
        control = new PointF(0, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        Path path = new Path();
        path.moveTo(start.x, start.y);
        path.quadTo(control.x, control.y, end.x, end.y);

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        super.onSizeChanged(w, h, oldw, oldh);
        centerX = w / 2;
        centerY = h / 2;

        start.x = centerX – 200;
        start.y = centerY;
        end.x = centerX + 200;
        end.y = centerY;
        control.x = centerX;
        control.y = centerY – 100;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        control.x = event.getX();
        control.y = event.getY();
        invalidate();
        return true;
    }
}
        
        

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153541.html

(0)
上一篇 2025-03-03 15:45
下一篇 2025-03-03 16:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信