栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

直播页面8:自定义View贝塞尔曲线

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

直播页面8:自定义View贝塞尔曲线

直播页面8:自定义View贝塞尔曲线
  • 一.绘制一阶
  • 二.绘制二阶和三阶
  • 三.绘制辅助线和控制点
  • 四.勾股定理:碰撞测试
    • 1.碰撞测试
    • 2.事件处理
    • 3.全部代码

一.绘制一阶
public class BezierView extends View {
    private Path mPath;//路径
    private Paint mPaint;//画笔
    //java代码
    public BezierView(Context context) {
        super(context);
        initPaint();
    }
    //xml布局
    public BezierView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private void initPaint() {
        //画笔
        mPaint = new Paint();
        //设置样式 STROKE:空心 FILL:实心
        mPaint.setStyle(Paint.Style.STROKE);
        //设置宽度
        mPaint.setStrokeWidth(20);
        //抗锯齿
        mPaint.setAntiAlias(true);
        //防抖动
        mPaint.setDither(true);
        //路径
        mPath = new Path();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制一阶曲线
        drawOneBezier(canvas);
    }
    //绘制一阶曲线
    private void drawOneBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,50);
        //路径终点
        mPath.lineTo(100,150);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
    }
}
二.绘制二阶和三阶

1.二阶: mPath.quadTo(twoControlX,twoControlY,100,150);
2.三阶:mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500);

public class BezierView extends View {
    private Path mPath;//路径
    private Paint mPaint;//画笔
    //二阶曲线的控制点
    public float twoControlX = 50;
    public float twoControlY = 50;

    //三阶曲线的控制点
    public float threeControlX1 = 200;
    public float threeControlY1 = 300;
    public float threeControlX2 = 400;
    public float threeControlY2 = 300;
    //java代码
    public BezierView(Context context) {
        super(context);
        initPaint();
    }
    //xml布局
    public BezierView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private void initPaint() {
        //画笔
        mPaint = new Paint();
        //设置样式 STROKE:空心 FILL:实心
        mPaint.setStyle(Paint.Style.STROKE);
        //设置宽度
        mPaint.setStrokeWidth(20);
        //抗锯齿
        mPaint.setAntiAlias(true);
        //防抖动
        mPaint.setDither(true);
        //路径
        mPath = new Path();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制一阶曲线
        drawOneBezier(canvas);
        //绘制二阶曲线
        drawTwoBezier(canvas);
        //绘制三阶曲线
        drawThreeBezier(canvas);
    }

    //绘制三阶曲线
    private void drawThreeBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,250);
        //绘制3阶
        mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500);        
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
    }

    //绘制二阶曲线
    private void drawTwoBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,250);
        //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y
        mPath.quadTo(twoControlX,twoControlY,100,150);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
    }

    //绘制一阶曲线
    private void drawOneBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,50);
        //路径终点
        mPath.lineTo(100,150);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
    }
}

三.绘制辅助线和控制点

 //绘制二阶曲线
    private void drawTwoBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,250);
        //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y
        mPath.quadTo(twoControlX,twoControlY,500,250);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();

        //---辅助线---
        //设置画笔的颜色
        mPaint.setColor(Color.YELLOW);
        //通过path对象移动到起点位置
        mPath.moveTo(50, 250);
        //画一个从起点到控制点的线
        mPath.lineTo( twoControlX, twoControlY);
        //从控制点到终点的线
        mPath.lineTo(500, 250);
        //绘制路径
        canvas.drawPath(mPath, mPaint);
        //重置路径
        mPath.reset();
        //---画出控制的点---
        //设置画笔的颜色
        mPaint.setColor(Color.GREEN);
        //画一个控制点的圆 圆心是控制点的X和Y 半径是10
        canvas.drawCircle( twoControlX, twoControlY, 10, mPaint);
        //重置路径
        mPath.reset();
    }
//绘制三阶曲线
    private void drawThreeBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,500);
        //绘制3阶
        mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
        //---辅助线---
        mPaint.setColor(Color.YELLOW);
        //通过path对象移动到起点位置
        mPath.moveTo(50, 500);
        //从起点画到第一个控制点
        mPath.lineTo( threeControlX1, threeControlY1);
        //从第一个控制点画到第二个控制点
        mPath.lineTo( threeControlX2,  threeControlY2);
        //从第二个控制点画到终点
        mPath.lineTo(500, 500);
        //绘制路径
        canvas.drawPath(mPath, mPaint);
        //重置路径
        mPath.reset();


        //---画出控制的点---
        mPaint.setColor(Color.GREEN);
        //画二个控制点的圆 圆心是控制点的X和Y 半径是10
        canvas.drawCircle( threeControlX1, threeControlY1, 10, mPaint);
        canvas.drawCircle( threeControlX2,  threeControlY2, 10, mPaint);
    }
四.勾股定理:碰撞测试 1.碰撞测试
   //判断手指的触点是否在圆内,碰撞判断
    private boolean isChekCircle(PointF pointF, PointF circle, float radius) {
        return Math.pow((pointF.x - circle.x),2)+Math.pow((pointF.y-circle.y),2)<= Math.pow(radius,2);
    }
2.事件处理
 //消费后做处理 getAction Down Move Up
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            //当手指按下得时候
            case MotionEvent.ACTION_DOWN:
                //判断二阶得点有没有被点击到
                boolean twoControl = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) twoControlX, (float) twoControlY), 50);
                //判断三阶得点有没有被点击到
                boolean threeControl1 = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) threeControlX1, (float) threeControlY1), 50);
                boolean threeControl2 = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) threeControlX2, (float) threeControlY2), 50);
                if (twoControl) {
                    mType = 0;
                } else if (threeControl1) {
                    mType = 1;
                } else if (threeControl2) {
                    mType = 2;
                } else {
                    mType = -1;
                }


                break;
            //当手指移动得时候
            case MotionEvent.ACTION_MOVE:
                //将当前得点赋值给二阶贝塞尔曲线得控制点
                if (mType == 0) {
                    twoControlX = event.getX();
                    twoControlY = event.getY();
                    invalidate();
                    //将当前得点赋值给三阶贝塞尔曲线得控制点1

                } else if (mType == 1) {

                    threeControlX1 = event.getX();
                    threeControlY1 = event.getY();
                    invalidate();
//                    将当前得点赋值给三阶贝塞尔曲线得控制点2
                } else if (mType == 2) {
                    threeControlX2 = event.getX();
                    threeControlY2 = event.getY();
                    invalidate();
                }

                break;

            case MotionEvent.ACTION_UP:
                break;
        }

        return true;

    }
3.全部代码
public class BezierView extends View {
    private Path mPath;//路径
    private Paint mPaint;//画笔
    //二阶曲线的控制点
    public float twoControlX = 50;
    public float twoControlY = 50;

    //三阶曲线的控制点
    public float threeControlX1 = 200;
    public float threeControlY1 = 300;
    public float threeControlX2 = 400;
    public float threeControlY2 = 300;
    //判断碰撞
    private int mType;
    //java代码
    public BezierView(Context context) {
        super(context);
        initPaint();
    }
    //xml布局
    public BezierView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private void initPaint() {
        //画笔
        mPaint = new Paint();
        //设置样式 STROKE:空心 FILL:实心
        mPaint.setStyle(Paint.Style.STROKE);
        //设置宽度
        mPaint.setStrokeWidth(20);
        //抗锯齿
        mPaint.setAntiAlias(true);
        //防抖动
        mPaint.setDither(true);
        //路径
        mPath = new Path();
    }

    //测量View的大小
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //单独测量宽高
        int w = measureSingle(widthMeasureSpec);
        int h = measureSingle(heightMeasureSpec);
        //设置宽高
        setMeasuredDimension(w, h);

    }

    //单独测量
    private int measureSingle(int measureSpec) {
        int result = 0;
        //测量模式
        int mode = MeasureSpec.getMode(measureSpec);
        //测量大小
        int size = MeasureSpec.getSize(measureSpec);
        //当是无限模式 返回200
        if (mode == MeasureSpec.AT_MOST) {//当WRAP
            result = 500;
        } else {
            result = size;
        }
        return result;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制一阶曲线
        drawOneBezier(canvas);
        //绘制二阶曲线
        drawTwoBezier(canvas);
        //绘制三阶曲线
        drawThreeBezier(canvas);
    }

    //绘制三阶曲线
    private void drawThreeBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,500);
        //绘制3阶
        mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
        //---辅助线---
        mPaint.setColor(Color.YELLOW);
        //通过path对象移动到起点位置
        mPath.moveTo(50, 500);
        //从起点画到第一个控制点
        mPath.lineTo( threeControlX1, threeControlY1);
        //从第一个控制点画到第二个控制点
        mPath.lineTo( threeControlX2,  threeControlY2);
        //从第二个控制点画到终点
        mPath.lineTo(500, 500);
        //绘制路径
        canvas.drawPath(mPath, mPaint);
        //重置路径
        mPath.reset();


        //---画出控制的点---
        mPaint.setColor(Color.GREEN);
        //画二个控制点的圆 圆心是控制点的X和Y 半径是10
        canvas.drawCircle( threeControlX1, threeControlY1, 10, mPaint);
        canvas.drawCircle( threeControlX2,  threeControlY2, 10, mPaint);
    }

    //绘制二阶曲线
    private void drawTwoBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,250);
        //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y
        mPath.quadTo(twoControlX,twoControlY,500,250);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();

        //---辅助线---
        //设置画笔的颜色
        mPaint.setColor(Color.YELLOW);
        //通过path对象移动到起点位置
        mPath.moveTo(50, 250);
        //画一个从起点到控制点的线
        mPath.lineTo( twoControlX, twoControlY);
        //从控制点到终点的线
        mPath.lineTo(500, 250);
        //绘制路径
        canvas.drawPath(mPath, mPaint);
        //重置路径
        mPath.reset();
        //---画出控制的点---
        //设置画笔的颜色
        mPaint.setColor(Color.GREEN);
        //画一个控制点的圆 圆心是控制点的X和Y 半径是10
        canvas.drawCircle( twoControlX, twoControlY, 10, mPaint);
        //重置路径
        mPath.reset();
    }

    //绘制一阶曲线
    private void drawOneBezier(Canvas canvas) {
        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //路径起点
        mPath.moveTo(50,50);
        //路径终点
        mPath.lineTo(100,150);
        //绘制路径
        canvas.drawPath(mPath,mPaint);
        //重置路径
        mPath.reset();
    }
    //生成一个事务
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

    //消费后做处理 getAction Down Move Up
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            //当手指按下得时候
            case MotionEvent.ACTION_DOWN:
                //判断二阶得点有没有被点击到
                boolean twoControl = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) twoControlX, (float) twoControlY), 50);
                //判断三阶得点有没有被点击到
                boolean threeControl1 = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) threeControlX1, (float) threeControlY1), 50);
                boolean threeControl2 = isChekCircle(new PointF(event.getX(), event.getY()),
                        new PointF((float) threeControlX2, (float) threeControlY2), 50);
                if (twoControl) {
                    mType = 0;
                } else if (threeControl1) {
                    mType = 1;
                } else if (threeControl2) {
                    mType = 2;
                } else {
                    mType = -1;
                }


                break;
            //当手指移动得时候
            case MotionEvent.ACTION_MOVE:
                //将当前得点赋值给二阶贝塞尔曲线得控制点
                if (mType == 0) {
                    twoControlX = event.getX();
                    twoControlY = event.getY();
                    invalidate();
                    //将当前得点赋值给三阶贝塞尔曲线得控制点1

                } else if (mType == 1) {

                    threeControlX1 = event.getX();
                    threeControlY1 = event.getY();
                    invalidate();
//                    将当前得点赋值给三阶贝塞尔曲线得控制点2
                } else if (mType == 2) {
                    threeControlX2 = event.getX();
                    threeControlY2 = event.getY();
                    invalidate();
                }

                break;

            case MotionEvent.ACTION_UP:
                break;
        }

        return true;

    }

    //判断手指的触点是否在圆内,碰撞判断
    private boolean isChekCircle(PointF pointF, PointF circle, float radius) {
        return Math.sqrt(Math.pow((pointF.x - circle.x), 2) + Math.pow((pointF.y - circle.y), 2)) <= radius;
    }

}
转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1040540.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号