Android Path方法總結(jié)

常用方法

1.moveTo(float x, float y)

移動下一次操作的起點位置

2.lineTo(float x, float y)

添加上一個點到當前點之間的直線到Path

3. close()

連接第一個點連接到最后一個點,形成一個閉合區(qū)域

4.addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo

添加(矩形, 圓角矩形, 橢圓, 圓, 路徑, 圓弧) 到當前Path

4.isEmpty()

判斷Path是否為空

5.isRect()

判斷path是否是一個矩形

6.set(@NonNull Path src)

用新的路徑替換到當前路徑所有內(nèi)容

7.offset(float dx, float dy)/offset(float dx, float dy, @Nullable Path dst)

對當前路徑之前的操作進行偏移

8.quadTo, cubicTo

分別為二次和三次貝塞爾曲線的方法

http://www.itdecent.cn/p/582545122a7a

9.rMoveTo, rLineTo, rQuadTo, rCubicTo

不帶r的方法是基于原點的坐標系(偏移量),rXxx方法是基于當前點坐標系(偏移量)

10.setFillType, getFillType, isInverseFillType, toggleInverseFillType

設(shè)置,獲取,判斷和切換填充模式

11.op

對兩個Path進行布爾運算(即取交集、并集等操作)

12.computeBounds

計算Path的邊界

13.reset, rewind

清除Path中的內(nèi)容(reset相當于重置到new Path階段,rewind會保留Path的數(shù)據(jù)結(jié)構(gòu))

14.transform

矩陣變換

PathMeasure

是一個用來測量Path的類
forceClosed就是Path最終是否需要閉合,如果為True的話,則不管關(guān)聯(lián)的Path是否是閉合的,都會被閉合,forceClosed對綁定的Path不會產(chǎn)生任何影響

Path path = new Path();
path.lineTo(0, 200);
path.lineTo(200, 200);
path.lineTo(200, 0);
PathMeasure measure = new PathMeasure(path, forceClosed);
float length = measure.getLength();

getSegment

boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)

這個API用于截取整個Path的片段,通過參數(shù)startD和stopD來控制截取的長度,并將截取的Path保存到dst中,最后一個參數(shù)startWithMoveTo表示起始點是否使用moveTo方法,通常為True,保證每次截取的Path片段都是正常的、完整的。
如果startWithMoveTo設(shè)置為false,通常是和dst一起使用,因為dst中保存的Path是被不斷添加的,而不是每次被覆蓋,設(shè)置為false,則新增的片段會從上一次Path終點開始計算,這樣可以保存截取的Path片段數(shù)組連續(xù)起來。
由于硬件加速的問題,PathMeasure中的getSegment在講Path添加到dst數(shù)組中時會被導(dǎo)致一些錯誤,需要通過mDst.lineTo(0,0)來避免這樣一個Bug。

    Path path = new Path();
        path.addRect(-200, -200, 200, 200, Path.Direction.CW);

        PathMeasure measure = new PathMeasure(path, false);
        canvas.drawPath(path, paint);

        Path dst = new Path();
        dst.lineTo(-300, -300);

        measure.getSegment(200, 600, dst , false);
        paint.setColor(Color.GREEN);

        canvas.drawPath(dst, paint);

路徑繪制是PathMeasure最常用的功能,其原理就是通過getSegment來不斷截取Path片段,從而不斷繪制完整的路徑
例如:

public class PathPainter extends View {

    private Path mPath;
    private Paint mPaint;
    private PathMeasure mPathMeasure;
    private float mAnimatorValue;
    private Path mDst;
    private float mLength;

    public PathPainter(Context context) {
        super(context);
    }

    public PathPainter(Context context, AttributeSet attrs) {
        super(context, attrs);
        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.CW);
        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();
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mDst.reset();
        // 硬件加速的BUG
        mDst.lineTo(0,0);
        float stop = mLength * mAnimatorValue;
        mPathMeasure.getSegment(0, stop, mDst, true);
        canvas.drawPath(mDst, mPaint);
    }
}

loading.gif

同樣的效果也可以用DashPathEffect來實現(xiàn)

nextContour

如果有一個Path,包含了多個Path,那么通過nextContour這個方法,就可以進行切換

    Path path = new Path();
    path.addRect(-200, -200, 200, 200, Path.Direction.CW);
    path.addRect(-100, -100, 100, 100, Path.Direction.CW);

    PathMeasure measure = new PathMeasure(path, false);
    float length = measure.getLength();
    boolean nextContour = measure.nextContour();
    float length2 = measure.getLength();

getPosTan

boolean getPosTan (float distance, float[] pos, float[] tan)
通過指定distance(0<distance<getLength),來獲取坐標點和切線的坐標,并保存到pos[]和tan[]數(shù)組中

Path path = new Path();
path.addCircle(0, 0, 300, Path.Direction.CW);
        
PathMeasure measure = new PathMeasure(path, false);
float[] pos = new float[2];
float[] tan = new float[2];
measure.getPosTan(measure.getLength()/4, pos , tan );
//獲取切點角度
 float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);

getMatrix

這個方法是用于得到路徑上某一長度的位置以及該位置的正切值的矩陣:
boolean getMatrix (float distance, Matrix matrix, int flags)
最后一個參數(shù)規(guī)定哪些內(nèi)容會存入到matrix中,可選擇:

POSITION_MATRIX_FLAG(位置)
ANGENT_MATRIX_FLAG(正切)

返回值true表示成功,數(shù)據(jù)會存入matrix中,false 失敗,matrix內(nèi)容不會改變

PathEffect

PathEffect見文知意很明顯就是路徑效果的意思

CornerPathEffect

可以使用圓角來代替尖銳的角從而對基本圖形的形狀尖銳的邊角進行平滑

mEffects[1] = new CornerPathEffect(50);

CornerPathEffect的構(gòu)造方法只接受一個參數(shù)radius,意思就是轉(zhuǎn)角處的圓滑程度

DashPathEffect

DashPathEffect來創(chuàng)建一個虛線的輪廓(短橫線/小圓點),而不是使用實線。你還可以指定任意的虛/實線段的重復(fù)模式,第一個參數(shù)是一個浮點型的數(shù)組,那這個數(shù)組有什么意義呢?其實是這樣的,我們在定義該參數(shù)的時候只要浮點型數(shù)組中元素個數(shù)大于等于2即可

mEffects[3] = new DashPathEffect(new float[] {20, 10}, mPhase);

float[] {20, 10}的偶數(shù)參數(shù)20(注意數(shù)組下標是從0開始哦)定義了我們第一條實線的長度,而奇數(shù)參數(shù)10則表示第一條虛線的長度,如果此時數(shù)組后面不再有數(shù)據(jù)則重復(fù)第一個數(shù)以此往復(fù)循環(huán),比如我們20,10后沒數(shù)了,那么整條線就成了[20,10,20,10,20,10…………………………]這么一個狀態(tài),DashPathEffect的第二個參數(shù)我稱之為偏移值,動態(tài)改變其值會讓路徑產(chǎn)生動畫的效果

PathDashPathEffect

這種效果可以定義一個新的形狀(路徑)并將其用作原始路徑的輪廓標記。

ComposePathEffect

將兩種效果組合起來應(yīng)用,先使用第一種效果,然后在這種效果的基礎(chǔ)上應(yīng)用第二種效果。

SumPathEffect

順序地在一條路徑中添加兩種效果,這樣每一種效果都可以應(yīng)用到原始路徑中,而且兩種結(jié)果可以結(jié)合起來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容