前言
之前講過Paint和Canvas的基本使用,今天來介紹下Path的使用
涉及內容有:
- Path畫直線路徑
- Path畫弧線路徑
- PathView引用說明
- 項目結構圖和效果圖
一. Path畫直線路徑
Path畫直線路徑的步驟分三步:
第一步:設置path的起點,代碼如下:
path.moveTo(float x,float y);//設置path的起點
第二步:設置下一個路徑點,代碼如下:
path.lineTo(float x,float y);//設置下一個路徑點
注意:path的lineTo方法可以不斷使用。
第三步:封閉形成閉環,代碼如下:
path.close();
注意:第三步的調用不是必須的,只有當你連續LineTo了幾條直線以后,想形成一個封閉的空間的時候,可以直接調用此方法,而不用又費力的調用lineTo回到原點。
二. Path畫弧線路徑
path畫弧線的方法常用的有如下幾個:
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo);
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) ;
其實第一個和第二個大同小異,只是第一個是傳入一個RectF,而第二個是直接將構造RectF的參數傳進去而已。這里以講解
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo);
為例,方法很簡單,但是理解是個問題。下面着重介紹arcTo方法的幾個參數的意義,幫助大家理解。
2.1 RectF oval 參數
書本解釋是:生成橢圓的矩形。
這里大家注意一點,如果矩形是長方形,那么生成的是橢圓,如果矩形是正方形的時候,生成的就是圓了。
這里解釋讓人感覺生硬,不好理解,那么這個RectF和弧線到底啥關系,讓我們用代碼解釋:
//設置paint
Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
//設置Path
Path path=new Path();
RectF rectF=new RectF();
rectF.set(340,350,740,550);
//畫矩形
canvas.drawRect(rectF,paint);
paint.setColor(Color.BLUE);
path.arcTo(rectF,0,90,false);
//畫弧線
canvas.drawPath(path,paint);
效果圖如下:
測試矩形畫弧線
下面看下,當矩形為正方形的情況:
//設置paint
Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
//設置Path
Path path=new Path();
RectF rectF=new RectF(340,600,740,1000);
//畫正方形
canvas.drawRect(rectF,paint);
//畫弧線
paint.setColor(Color.BLUE);
path.arcTo(rectF,0,90,false);
canvas.drawPath(path,paint);
效果圖如下:
測試正方形畫矩形
由上兩個示例不難看出,RectF和弧線的關系是,RectF是弧線所在圓或橢圓的外切矩形,當RectF為長方形的時候,弧線為其內切橢圓上的一段軌跡,當RectF為正方形的時候,弧線為其內切圓上的一段軌跡,也不難推斷,弧線所在幾何中心或圓心即為RectF的幾何中心。
2.2 float startAngle, float sweepAngle 參數
書本解釋:
float startAngle:弧開始的角度,以x軸正方向為0度
float sweepAngle:弧持續的弧度
在2.1中,我設置的畫弧代碼均是:
path.arcTo(rectF,0,90,false);
即 startAngle=0,sweepAngle =90,與上面的書本解釋相結合,我們可以這樣理解,當弧線切線角度為0°的時候開始畫弧,直到當弧線的切線角度為90°的時候,停止畫弧。
2.3 boolean forceMoveTo 參數
在Path畫圖的過程中,除了addXXX系列函數和moveTo()方法外,路徑默認都是連貫的。而forceMoveTo 則是設置弧線與畫弧線之前的“最后一筆”是否強制不連接。當 forceMoveTo =false 時,表示連接,當 forceMoveTo =true時,表示不連接。
下面以示例說明:
當 forceMoveTo =false時:
Paint paint=new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
Path path=new Path();
path.moveTo(540,1400);//設置path初始點,模仿畫弧前"最后一筆"
//畫弧線
RectF rectF=new RectF(50,1050,490,1350);
path.arcTo(rectF,0,90,false);
canvas.drawPath(path,paint);
效果圖:
測試forceMoveTo=false
當 forceMoveTo =true 時:
Paint paint=new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
Path path=new Path();
path.moveTo(540,1400);//設置path初始點,模仿畫弧前"最后一筆"
//畫弧線
RectF rectF=new RectF(50,1050,490,1350);
path.arcTo(rectF,0,90,true);
canvas.drawPath(path,paint);
效果圖如下:
測試forceMoveTo=true
2.4 arcTo 方法需要注意的地方
Path的 arcTo 方法是用來畫弧線的,不能用來畫圓,當你代碼如下設置的時候:
path.arcTo(rectf,0,360,true);
時,將無法畫出一個圓,因為弧的弧度不能為360°,當你設置的度數大於360°的時候,實際畫出的弧度為你設置的度數減去360°得到的度數,例如下面:
//設置畫筆
Paint paint=new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
//設置路徑
Path path=new Path();
RectF rectF=new RectF(590,1050,1030,1350);
path.arcTo(rectF,0,400,true);
canvas.drawPath(path,paint);
效果圖如下:
超過360度
三. PathView引用說明
所有的測試代碼我都封裝到了PathView控件中,下面貼出PathView中主要代碼:
//初始化
init(canvas);
//path畫直線
drawLinePath(canvas);
//Path畫弧線
drawArcPath(canvas);
//測試畫弧線
drawActPathTest(canvas);
//測試長方形和弧線的關系
testOneArcTo(canvas);
//測試正方形和弧線的關系
testTwoArcTo(canvas);
// //測試 forceMoveTo =false
// testForceMoveTo(canvas,false);
//測試 forceMoveTo =true
testForceMoveTo(canvas,true);
//測試度數超過360
testMore360(canvas);
PathView在MainActivity對應的activity_main.xml中的引用如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.testdemo.main.MainActivity">
<com.android.testdemo.function.PathView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
四. 項目結構圖和效果圖
項目結構圖
效果圖
Path畫直線與弧線