Android PathMeasure的使用


參考:

https://blog.csdn.net/weixin_33935505/article/details/88000720

https://blog.csdn.net/coderinchina/article/details/53665632

PathMeasure基本概念

路徑測量,一個用來測量Path的工具類

PathMeasure常用API

常用API如Path長度測量,Path跳轉,Path片段獲取等。

PathMeasure案例實現

先畫座標軸

    private int mViewWidth;
    private int mViewHeight;

    private Paint mDeafultPaint;
    private Paint mPaint;

    public MyView(Context context) {
        super(context);
        init();
    }

    private void init() {
        mDeafultPaint = new Paint();
        mDeafultPaint.setColor(Color.RED);
        mDeafultPaint.setStrokeWidth(5);
        mDeafultPaint.setStyle(Paint.Style.STROKE);

        mPaint = new Paint();
        mPaint.setColor(Color.DKGRAY);
        mPaint.setStrokeWidth(2);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        Log.i(TAG, "onSizeChanged" + "w = " + w + ", h = " + h + ", oldw = " + oldw + ", oldh = " + oldh);
        mViewWidth = w;
        mViewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG, "onDraw");
        // 平移座標系
        canvas.translate(mViewWidth / 2, mViewHeight / 2);
        // 畫座標線
        canvas.drawLine(-canvas.getWidth(), 0, canvas.getWidth(), 0, mPaint);
        canvas.drawLine(0, -canvas.getHeight(), 0, canvas.getHeight(), mPaint);

//        testForceClosed(canvas);
 //       testNextContour(canvas);
//        testGetSegment(canvas);
//        testGetSegmentMoveTo(canvas);
    }

forceClosed

    private void testForceClosed(Canvas canvas) {
        Path path = new Path();

        path.lineTo(0, 200);
        path.lineTo(200, 200);
        path.lineTo(200, 0);

        PathMeasure measure1 = new PathMeasure(path, false);
        //一但測量如果是閉合狀態,那麼不管原型的Path是怎樣的,
        //這邊在進行測量的時候回默認閉合
        //Path的測量不會影響原本的Path
        PathMeasure measure2 = new PathMeasure(path, true);

        Log.i(TAG, "forceClosed=false length = " + measure1.getLength());
        Log.i(TAG, "forceClosed=true length = " + measure2.getLength());
//        path.close();
        canvas.drawPath(path, mDeafultPaint);

    }

在這裏插入圖片描述

打印結果:

forceClosed=false length = 600.0
forceClosed=true length = 800.0

1、不論 forceClosed 設置爲何種狀態(true 或者 false),都不會影響原有Path的狀態,即 Path 與 PathMeasure 關聯之後,之前的Path 不會有任何改變

2、forceClosed 的設置狀態可能會影響測量結果,如果 Path 未閉合但在與 PathMeasure 關聯的時候設置 forceClosed 爲 true 時,測量結果可能會比 Path 實際長度稍長一點.


nextContour

方法描述: 獲取在路徑中下一個輪廓,如果有下一個輪廓,則返回true,且PathMeasure切至下一個輪廓的數據;如果沒有下一個輪廓則返回false。

    private void testNextContour(Canvas canvas) {
        Path path = new Path();
        Path path1 = new Path();
        Path path2 = new Path();
        // 添加小矩形
        path1.addRect(-100, -100, 100, 100, Path.Direction.CW);
        PathMeasure measure2 = new PathMeasure(path1, false);
        Log.i(TAG,"path1:"+measure2.getLength());

        // 添加大矩形
        //path.addRect(-200, 200, 200, 600, Path.Direction.CW);
        path2.addRect(-200, -200, 200, 200, Path.Direction.CW);

        PathMeasure measure3 = new PathMeasure(path2, false);
        Log.i(TAG,"path2:"+measure3.getLength());

        /**
         * 對兩個Path進行布爾運算
         * XOR保留path1與path2不共同的部分;
         */
        path.op(path1,path2, Path.Op.XOR);
        canvas.drawPath(path,mDeafultPaint);

        PathMeasure measure = new PathMeasure(path, false);
        Log.i(TAG,"path:"+measure.getLength());
        float[] tan = new float[2];
        float[] pos = new float[2];


        //三個參數
        //distance 指定Path路徑上的長度
//        兩個長度爲2的浮點數組,這個數組時用來接收數據
        //tan 當前位置的正切點XY
        //pos 當前Path路徑點的XY
        measure.getPosTan(50f,pos,tan);
        Log.i(TAG,"----------------------pos[0] = " + pos[0] + "---pos[1] = " +pos[1]);
        Log.i(TAG,"----------------------tan[0] = " + tan[0] + "---tan[1] = " +tan[1]);
        canvas.drawLine(tan[0],tan[1],pos[0],pos[1],mPaint);

        float len1 = measure.getLength();
        // 跳轉到下一條路徑
        measure.nextContour();

        measure.getPosTan(0f,pos,tan);
        Log.i(TAG,"----------------------pos[0] = " + pos[0] + "pos[1] = " +pos[1]);
        Log.i(TAG,"----------------------tan[0] = " + tan[0] + "tan[1] = " +tan[1]);
        canvas.drawLine(tan[0],tan[1],pos[0],pos[1],mDeafultPaint);
        float len2 = measure.getLength();
        Log.i(TAG,"len1 = "+len1);
        Log.i(TAG,"len2 = "+len2);
    }
path1:800.0
path2:1600.0
path:1600.0
----------------------pos[0] = 150.0,  pos[1] = -200.0
----------------------tan[0] = -1.0,  tan[1] = 0.0
----------------------pos[0] = 100.0,  pos[1] = -100.0
----------------------tan[0] = -1.0,  tan[1] = 0.0
 len1 = 1600.0
 len2 = 800.0

在這裏插入圖片描述

getSegment

方法描述: 獲取關聯的path的片段路徑,添加至dst路徑中(並非替換,是增加)

返回值:
1、爲true時,說明截取成功,添加至dst路徑中;
2、爲false時,說明截取失敗,dst路徑不變動;

    /**
     * 路徑截取,且不移動開始點
     */
    private void testGetSegment(Canvas canvas) {
        Path path = new Path();
        // 創建Path並添加了一個矩形(順時針)
        path.addRect(-200, -200, 200, 200, Path.Direction.CW);
        Path dst = new Path();
        // 將 Path 與 PathMeasure 關聯
        PathMeasure measure = new PathMeasure(path, false);
        // 截取一部分存入dst中,並使用 moveTo 保持截取得到的 Path 第一個點的位置不變
        measure.getSegment(200, 600, dst, true);
        canvas.drawPath(path, mPaint);
        // 繪製 dst
        canvas.drawPath(dst, mDeafultPaint);
    }

在這裏插入圖片描述

    /**
     * 路徑截取,移動開始點
     */
    private void testGetSegmentMoveTo(Canvas canvas) {
        Path path = new Path();
        // 創建Path並添加了一個矩形
        path.addRect(-200, -200, 200, 200, Path.Direction.CW);
        Path dst = new Path();
        dst.lineTo(-300, -300);
        // 將 Path 與 PathMeasure 關聯
        PathMeasure measure = new PathMeasure(path, false);
        // 截取一部分存入dst中,並使用 moveTo 保持截取得到的 Path 第一個點的位置不變
        measure.getSegment(200, 600, dst, false);
        //measure.getSegment(200, 600, dst, true);
        canvas.drawPath(path, mPaint);
        // 繪製 dst
        canvas.drawPath(dst, mDeafultPaint);
    }

在這裏插入圖片描述

示例:箭頭圍繞圓運動

/**
 * 箭頭圍繞圓運動
 */
public class PathMeasureView extends View {
    private float currentValue = 0;     // 用於紀錄當前的位置,取值範圍[0,1]映射Path的整個長度

    private float[] pos;                // 當前點的實際位置
    private float[] tan;                // 當前點的tangent值,用於計算圖片所需旋轉的角度
    private Bitmap mBitmap;             // 箭頭圖片
    private Matrix mMatrix;             // 矩陣,用於對圖片進行一些操作
    private Paint mDeafultPaint;
    private int mViewWidth;
    private int mViewHeight;
    private Paint mPaint;

    public PathMeasureView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        pos = new float[2];
        tan = new float[2];
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;       // 縮放圖片
        mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options);
        mMatrix = new Matrix();

        mDeafultPaint = new Paint();
        mDeafultPaint.setColor(Color.RED);
        mDeafultPaint.setStrokeWidth(5);
        mDeafultPaint.setStyle(Paint.Style.STROKE);

        mPaint = new Paint();
        mPaint.setColor(Color.DKGRAY);
        mPaint.setStrokeWidth(2);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        // 平移座標系
        canvas.translate(mViewWidth/2,mViewHeight/2);
        // 畫座標線
        canvas.drawLine(-canvas.getWidth(),0,canvas.getWidth(),0,mPaint);
        canvas.drawLine(0,-canvas.getHeight(),0,canvas.getHeight(),mPaint);

        Path path = new Path();                                 // 創建 Path
        /**
         * Path.Direction.CCW 逆時針
         * Path.Direction.CW 順時針
         */
        path.addCircle(0, 0, 200, Path.Direction.CCW);           // 添加一個圓形
        PathMeasure measure = new PathMeasure(path, false);     // 創建 PathMeasure

        currentValue += 0.005;                                  // 計算當前的位置在總長度上的比例[0,1]
        if (currentValue >= 1) {
            currentValue = 0;
        }

//        // 方案一
//        // 獲取當前位置的座標以及趨勢
//        measure.getPosTan(measure.getLength() * currentValue, pos, tan);
//        canvas.drawCircle(tan[0],tan[1],20,mDeafultPaint);
//
//        // 重置Matrix
//        mMatrix.reset();
//        // 計算圖片旋轉角度(或弧度)
//        float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
//        // 旋轉圖片
//        mMatrix.postRotate(degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
//        // 將圖片繪製中心調整到與當前點重合
//        mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1] - mBitmap.getHeight() / 2);

        // 方案二
        // 獲取當前位置的座標以及趨勢的矩陣
        measure.getMatrix(measure.getLength() * currentValue, mMatrix,
        PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
        // 將圖片繪製中心調整到與當前點重合(偏移加旋轉)
        mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);
        canvas.drawPath(path, mDeafultPaint);
        canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint);

        invalidate();
    }
}

在這裏插入圖片描述

示例:圓圈加載

/**
 * 圓圈加載
 */
public class LoadingView extends View {
    private Path mPath;
    private Paint mPaint;
    private PathMeasure mPathMeasure;
    private float mAnimatorValue;
    private Path mDst;
    private float mLength;

    public LoadingView(Context context) {
        this(context,null);
    }

    public LoadingView(Context context, AttributeSet attrs) {
        this(context, attrs,0);

    }
    public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPathMeasure = new PathMeasure();
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPath = new Path();
        mPath.addCircle(400, 400, 100, Path.Direction.CCW);
        mPathMeasure.setPath(mPath, true);
        mLength = mPathMeasure.getLength();
        mDst = new Path();

        final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatorValue = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        valueAnimator.setDuration(2000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mDst.reset();
        // 硬件加速的BUG
        /**
         * 由於硬件加速的問題,PathMeasure中的getSegment添加到dst數組中時會被導致一些錯誤,
         * 需要通過mDst.lineTo(0,0)來避免這樣一個Bug。
         */
        mDst.lineTo(0,0);
        /*float stop = mLength * mAnimatorValue;
        mPathMeasure.getSegment(0, stop, mDst, true);*/

        float stop = mLength * mAnimatorValue;
        float start = (float) (stop - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * mLength));
        mPathMeasure.getSegment(start, stop, mDst, true);

        canvas.drawPath(mDst, mPaint);
    }
}

在這裏插入圖片描述

示例:笑臉加載

/**
 * 笑臉加載
 */
public class FaceLoadingView extends View {
    /**
     * 左眼距離左邊的距離(控件寬度*EYE_PERCENT_W),
     * 右眼距離右邊的距離(控件寬度*EYE_PERCENT_W)
     */
    private static final float EYE_PERCENT_W = 0.35F;
    /**
     * 眼睛距離top的距離(控件的高度*EYE_PERCENT_H)
     */
    private static final float EYE_PERCENT_H = 0.38F;
    /**
     * 嘴巴左邊跟右邊距離top的距離(控件的高度*MOUCH_PERCENT_H)
     */
    private static final float MOUCH_PERCENT_H = 0.55F;
    /**
     * 嘴巴中間距離top的距離(控件的高度*MOUCH_PERCENT_H2)
     */
    private static final float MOUCH_PERCENT_H2 = 0.7F;
    /**
     * 嘴巴左邊跟右邊距離邊緣的位置(控件寬度*MOUCH_PERCENT_W)
     */
    private static final float MOUCH_PERCENT_W = 0.23F;
    /**
     * 眼睛跟嘴巴擺動的區間範圍
     */
    private static final float DURATION_AREA = 0.15F;
    /**
     * 眼睛跟嘴巴擺動的動畫
     */
    Animation mAmin = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            float offset = interpolatedTime * DURATION_AREA;
            mMouchH = MOUCH_PERCENT_H + offset;
            mMouchH2 = MOUCH_PERCENT_H2 + offset;
            mEyesH = EYE_PERCENT_H + offset;
            postInvalidate();
        }
    };
    private Paint reachedPaint;
    private Paint unreachedPaint;
    private Path reachedPath;
    private Path unreachedPath;
    private Path mouthPath = new Path();

    private float mProgress = 0.1f;
    private float lineWidth = dp2px(2);

    private float mRadius;

    private float mMouchH = MOUCH_PERCENT_H;

    private float mMouchH2 = MOUCH_PERCENT_H2;

    private float mEyesH = EYE_PERCENT_H;

    public FaceLoadingView(Context context) {
        this(context, null);
    }

    public FaceLoadingView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FaceLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void startAni() {
        mAmin.setDuration(500);
        mAmin.setRepeatCount(Animation.INFINITE);
        mAmin.setRepeatMode(Animation.REVERSE);
        startAnimation(mAmin);
    }

    private void initView() {
        reachedPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        reachedPaint.setStyle(Paint.Style.STROKE);
        reachedPaint.setStrokeWidth(lineWidth);
        reachedPaint.setColor(Color.WHITE);
        reachedPaint.setStrokeJoin(Paint.Join.ROUND);
        reachedPaint.setStrokeCap(Paint.Cap.ROUND);


        unreachedPaint = new Paint(reachedPaint);
        unreachedPaint.setColor(Color.GRAY);
    }

    private boolean isStart = true;

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (isStart) {
            startAni();
            isStart = false;
        }
        mRadius = getWidth() / 7F / 2;
        if (unreachedPath == null) {
            unreachedPath = new Path();
        }
        unreachedPath.addRoundRect(new RectF(lineWidth, lineWidth, w - lineWidth, h - lineWidth), w / 6, w / 6, Path.Direction.CCW);
        if (reachedPath == null) {
            reachedPath = new Path();
        }
        reachedPath.addRoundRect(new RectF(lineWidth, lineWidth, w - lineWidth, h - lineWidth), w / 6, w / 6, Path.Direction.CW);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT);
        canvas.save();
        //draw face
        drawFace(canvas);
        //drawreached rect
        drawReachedRect(canvas);
        canvas.restore();
    }

    /**
     * draw face
     */
    private void drawFace(Canvas canvas) {
        unreachedPaint.setStyle(Paint.Style.FILL);
        //畫左邊的眼睛
        canvas.drawCircle(getWidth() * EYE_PERCENT_W, getHeight() * mEyesH - mRadius, mRadius, unreachedPaint);
        //畫右邊的眼睛
        canvas.drawCircle(getWidth() * (1 - EYE_PERCENT_W), getHeight() * mEyesH - mRadius, mRadius, unreachedPaint);
        mouthPath.reset();
        //畫嘴巴
        mouthPath.moveTo(getWidth() * MOUCH_PERCENT_W, getHeight() * mMouchH);
        mouthPath.quadTo(getWidth() / 2, getHeight() * mMouchH2, getWidth() * (1 - MOUCH_PERCENT_W), getHeight() * mMouchH);
        unreachedPaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(mouthPath, unreachedPaint);
    }

    private void drawReachedRect(Canvas canvas) {
        unreachedPaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(unreachedPath, unreachedPaint);
        PathMeasure measure = new PathMeasure(reachedPath, false);
        float length = measure.getLength();
        //獲取當前path長度
        float currLength = length * mProgress;
        Path path = new Path();
        /**
         * 因爲uc的起始位置是在頂部的位置,而我們的path的起始位置是在左下的位置,
         * 所以我們需要加上一個length*1/3f偏移量
         */
        measure.getSegment(length * 1 / 3f, currLength + length * 1 / 3f, path, true);
        canvas.drawPath(path, reachedPaint);
        /**
         * 當mProgress>=2/3f的時候,也就是回到了起點的時候,我們得截取兩段path了
         * 一段是1/3的位置到2/3
         * 一段是0到1/3的位置
         */
//        if(mProgress>=2/3f){
//            Path path2=new Path();
//            measure.getSegment(0,length*(mProgress-2/3f),path2,true);
//            canvas.drawPath(path2,reachedPaint);
//        }

    }

    public float dp2px(float dpValue) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, getResources().getDisplayMetrics());
    }

    public void setProgress(float progress) {
        Log.d("TAG", "" + progress);
        if (progress < mProgress) {
            return;
        }
        this.mProgress = progress;

        postInvalidate();

    }

    public void loadComplete() {
        mAmin.cancel();
        clearAnimation();
        setVisibility(View.GONE);
    }
}
        faceview = (FaceLoadingView) findViewById(R.id.faceview);
        faceview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (progress <= 100){
                            progress += 2;
                            faceview.setProgress(progress / 100);
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }

                    }
                }).start();

            }
        });

在這裏插入圖片描述

示例:小船滑動

/**
 * 小船滑動
 */
public class WaveView extends View {
    private static final int INT_WAVE_LENGTH = 1000;
    private static final String TAG = "WaveView";

    private Path mPath;
    private Paint mPaint;

    private int mDeltaX;
    private Bitmap mBitMap;
    private PathMeasure mPathMeasure;
    private float[] pos;
    private float[] tan;
    private Matrix mMatrix;
    private float faction;

    public WaveView(Context context) {
        super(context);
        init();

    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);

        mPath = new Path();
        pos = new float[2];
        tan = new float[2];
        mMatrix = new Matrix();

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize =  2;
        mBitMap = BitmapFactory.decodeResource(getResources(),R.drawable.timg,options);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        int orginY = 800;
        int halfWaveLength = INT_WAVE_LENGTH / 2;
        mPath.moveTo(-INT_WAVE_LENGTH + mDeltaX, orginY);
        for(int i = -INT_WAVE_LENGTH ; i < getWidth() + INT_WAVE_LENGTH;
            i += INT_WAVE_LENGTH){
            mPath.rQuadTo(halfWaveLength/2,120,halfWaveLength,0);
            mPath.rQuadTo(halfWaveLength/2,-120,halfWaveLength,0);
        }
        mPath.lineTo(getWidth(),getHeight());
        mPath.lineTo(0,getHeight());
        mPath.close();



        canvas.drawPath(mPath,mPaint);

        mPathMeasure = new PathMeasure(mPath,false);
        float length = mPathMeasure.getLength();
        mMatrix.reset();
        boolean posTan = mPathMeasure.getPosTan(length*faction,pos,tan);


        canvas.drawCircle(tan[0],tan[1],20,mPaint);
        canvas.drawLine(tan[0],tan[1],pos[0],pos[1],mPaint);

        Log.i(TAG,"----------------------pos[0] = " + pos[0] + "pos[1] = " +pos[1]);
        Log.i(TAG,"----------------------tan[0] = " + tan[0] + "tan[1] = " +tan[1]);
        if(posTan){
            // 方案一 :自己計算
            // 將tan值通過反正切函數得到對應的弧度,在轉化成對應的角度度數
            /*float degrees = (float) (Math.atan2(tan[1],tan[0])*180f / Math.PI);
            mMatrix.postRotate(degrees, mBitMap.getWidth()/2, mBitMap.getHeight() / 2);
            mMatrix.postTranslate(pos[0]- mBitMap.getWidth() / 2,pos[1] - mBitMap.getHeight());
            canvas.drawBitmap(mBitMap,mMatrix,mPaint);*/

            // 方案二 :直接使用API
            //直接幫你算了角度並且幫你進行了旋轉
            mPathMeasure.getMatrix(length*faction, mMatrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
            mMatrix.preTranslate(- mBitMap.getWidth() / 2, - mBitMap.getHeight());
            canvas.drawBitmap(mBitMap,mMatrix,mPaint);
        }

        //

    }

    public void startAnimation(){
//        ValueAnimator anim = ValueAnimator.ofInt(0,INT_WAVE_LENGTH);
//        anim.setDuration(1000);
//        anim.setInterpolator(new LinearInterpolator());
//        anim.setRepeatCount(ValueAnimator.INFINITE);
//        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//            @Override
//            public void onAnimationUpdate(ValueAnimator animation) {
//                mDeltaX = (int) animation.getAnimatedValue();
//                postInvalidate();
//            }
//        });
//        anim.start();

        ValueAnimator animator = ValueAnimator.ofFloat(0,1);
        animator.setDuration(10000);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                faction  = (float) animation.getAnimatedValue();
                Log.i(TAG,"----------------------faction = " + faction);
                postInvalidate();
            }
        });
        animator.start();
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章