搜索内容

有一个问题?

如果您有任何疑问,可以在下面询问或输入您要寻找的!

Android 自定义View 之 Path PathMeasure (一)

生成海报
LeeStudio_
LeeStudio_ 2020-09-05 16:46
阅读需:0

Path

  • path常见api

moveTo(float x, float y)挪动下一次实际操作的起始点部位
lineTo(float x, float y)加上上一个点到当今点中间的平行线到Path
addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo加上(矩形框, 圆角, 椭圆形, 圆, 途径, 弧形) 到当今Path
close()联接第一个点联接到最终一个点,产生一个合闭地区
quadTo, cubicTo各自为二次和三次贝塞尔曲线的方式
reset,rewind消除Path中的內容(reset等同于重设到new Path环节,rewind会保存Path的算法设计)

…也不列完后,之上便是Path大部分在开发设计中是用的频次较多的api

PathMeasure

  • pathMeasure 常见Api

getLength()回到当今轮廊的总长,要是没有途径与此衡量目标关系,则回到0。
getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)给出起始点和终点站的间距,回到提取的正中间段
setPath(Path path, boolean forceClosed)将新的精确测量途径分派给一个新Path,假如null 则无法显示。

它是最常见的精确测量PathMeasure Api

下列是融合新项目中对Path 和 PathMeasure 的应用案例:

项目可行性: 规定一个鼠标光标块在 矩形框上挪动,挪动速率可更为手机电池充电速率转变,如下图

在这里插入图片描述

有关API: addRoundRect(绘图矩形框)setPath(取值path途径)
reset(消除Path中的內容,消除以前的途径)getLength(获得途径的长短)
getSegment(提取一段path途径)

  • 重要编码

复位矩形框path而且精确测量这一path

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        segmentPath = new Path();
        path = new Path();
        path.addRoundRect(
                getPaddingLeft() + strokeWidth,
                getPaddingTop() + strokeWidth,
                getMeasuredWidth() - strokeWidth,
                getMeasuredHeight() - strokeWidth,
                100, 100, Path.Direction.CCW);
        pathMeasure.setPath(path, true);
    }

测算startD(提取精彩片段逐渐部位) stopD(提取精彩片段完毕部位),提取到精彩片段后取值给新的Path(鼠标光标挪动path)

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        segmentPath.reset();
        canvas.drawPath(path, paint);

        float length = pathMeasure.getLength();
        float stopD = mFloatPos * length;
        float startD = 0f;
        if (stopD < lineLength) {
            startD = 0;
        } else {
            startD = stopD - lineLength;
        }
        //提取精彩片段
        pathMeasure.getSegment(startD, stopD, segmentPath, true);
        canvas.drawPath(segmentPath, segmentPaint);

        if (stopD < lineLength) {
            float mStart2 = length - (lineLength - stopD);
            pathMeasure.getSegment(mStart2, length, segmentPath, true);
            canvas.drawPath(segmentPath, segmentPaint);
        }
    }

逐渐动漫,根据valueAnimator 动漫,能够试一下获得所在位置的信息内容 mFloatPost,随后根据mFloatPost
去测算StopD 的部位。

    public void startAnim() {
        if (valueAnimator == null) {
            valueAnimator = ValueAnimator.ofFloat(0, 1);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {


                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mFloatPos = (float) animation.getAnimatedValue();
                    invalidate();
                }
            });
            valueAnimator.setDuration(4000);
            valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.start();
        }
    }

    public void stopAnim() {
        if (valueAnimator != null) {
            valueAnimator.cancel();
            valueAnimator = null;
        }
    }
… 之上就重要编码
  • 应用方法
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        roundPathView = findViewById(R.id.round_path);
        roundPathView.startAnim();
    }
  @Override
    protected void onDestroy() {
        super.onDestroy();
        if (roundPathView!=null){
            roundPathView.stopAnim();
        }
    }
评论
  • 消灭零回复