Android使用繪圖Path總結

Path作為Android中一種相對復雜的繪圖方式,官方文檔中的有些解釋并不是很好理解,這里作一個相對全面一些的總結,供日后查看,也分享給大家,共同進步。

1.基本繪圖方法

  1. addArc(RectF oval, float startAngle, float sweepAngle)
    繪制弧線,配合Paint的Style可以實現不同的填充效果
  2. addCircle(float x, float y, float radius, Path.Direction dir)
    繪制圓形,其中第dir參數用來指定繪制時是順時針還是逆時針
  3. addOval(RectF oval, Path.Direction dir)
    繪制橢圓形,其中?oval作為橢圓的外切矩形區域
  4. addRect(RectF rect, Path.Direction dir)
    繪制矩形
  5. addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
    繪制圓角矩形
  6. lineTo(float x, float y)
    繪制直線
  7. addPath(Path src)
    添加一個新的Path到當前Path
  8. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
    addArc方法相似,但也有區別,下文細述。
  9. quadTo(float x1, float y1, float x2, float y2)
    繪制二次貝塞爾曲線,其中 (x1,y1)為控制點,(x2,y2)為終點
  10. cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
    繪制三次貝塞爾曲線,其中(x1,y1),(x2,y2)為控制點,(x3,y3)為終點

2.rXXX方法

上面的lineTo,MoveTo,QuadTo,CubicTo方法都有與之對應的rXXX方法:

  1. rLineTo(float dx, float dy)
  2. rMoveTo(float dx, float dy)
  3. rQuadTo(float dx1, float dy1, float dx2, float dy2)
  4. rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

這些方法與之對應的原方法相比,惟一的區別在于:r方法是基于當前繪制開始點的offest,比如當前paint位于 (100,100)處,則使用rLineTo(100,100)方法繪制出來的直線是從(100,100)到(200,200)的一條直接,由此可見rXXX方法方便用來基于之前的繪制作連續繪制。

3.Path.op方法

1
2
3
4
//原型
op(Path path, Path.Op op)
//eg
path1.op(path2,Path.Op.DIFFERENCE);

此方法用于對兩個Path對象做相應的運算組合(combine),具體的說是根據不同的op參數及path2參數來影響path1對象,有點類似于數學上的集合運算。請看下面的例子:

1
2
3
4
5
6
Path path1 = new Path();
path1.addCircle(150, 150, 100, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(200, 200, 100, Path.Direction.CW);
path1.op(path2, Path.Op.DIFFERENCE);
canvas.drawPath(path1, paint1);

效果如下:

通過不斷修改path1.op的第二個參數依次可以得到如下效果:

Path.Op.INTERSECT效果:

Path.Op.UNION效果:

Path.Op.REVERSE_DIFFERENCE效果:

Path.Op.XOR效果:

總結:
  1. Path.Op.DIFFERENCE 減去path1中path1與path2都存在的部分;
    path1 = (path1 - path1 ∩ path2)
  2. Path.Op.INTERSECT 保留path1與path2共同的部分;
    path1 = path1 ∩ path2
  3. Path.Op.UNION 取path1與path2的并集;
    path1 = path1 ∪ path2
  4. Path.Op.REVERSE_DIFFERENCE 與DIFFERENCE剛好相反;
    path1 = path2 - (path1 ∩ path2)
  5. Path.Op.XOR 與INTERSECT剛好相反;
    path1 = (path1 ∪ path2) - (path1 ∩ path2)

4.setFillType

設置path的填充模式.網上關于path的FillType的介紹很少,實際上在官方ApiDemos里就有個很好的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* Created by ghui on 10/25/15.
*/
public class PathFillTypeView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath;

public PathFillTypeView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);

mPath = new Path();
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
mPath.addCircle(120, 120, 45, Path.Direction.CCW);
}

private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, 160, 160);
canvas.drawColor(Color.WHITE);
mPath.setFillType(ft);
canvas.drawPath(mPath, paint);
canvas.restore();
}

@Override
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
paint.setColor(Color.RED);
canvas.drawColor(0xFFCCCCCC);
canvas.translate(20, 20);
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
showPath(canvas, 160 * 2, 0, Path.FillType.EVEN_ODD, paint);
showPath(canvas, 0, 160 * 2, Path.FillType.INVERSE_WINDING, paint);
showPath(canvas, 160 * 2, 160 * 2, Path.FillType.INVERSE_EVEN_ODD, paint);
}
}

效果如下:

(上面的例子在官方ApiDemo的基礎上做了適當的修改)

總結:

所謂填充指的就是填充內部,setFillType就是用來界定哪里算內部的算法。在計算機圖形學中界定一個點是不是在多邊形內部有兩種算法:

  1. 非零環繞數規則(Nonzero-rule)
  2. 奇偶規則(Even–odd rule)

關于這兩種算法這里不作詳細介紹,具體可以參考上面的維基鏈接,或者這篇中文資料(注意看評論區)

5.易混淆的方法

1. addArc 與 arcTo

前者指定在某處畫一條弧線,僅此而已,不會受當前paint的位置所影響。而arcTo方法有兩種形式:

  1. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
  2. arcTo(RectF oval, float startAngle, float sweepAngle)

    對于第一種形式的方法,若forceMoveTo參數為false,則與第二種形式的方法沒區別,繪制成的最終圖形會受到落筆點的影響;
    若forceMoveTo參數值為true,則繪制效果與addArc方法沒有區別。

1
2
3
4
5
//代碼1
Path path = new Path();
path.moveTo(100, 100);
path.addArc(200, 200, 400, 400, 0, 150);
canvas.drawPath(path, paint);

代碼1效果如下圖:

1
2
3
4
5
//代碼2
Path path = new Path();
path.moveTo(100, 100);
path.arcTo(200, 200, 400, 400, 0, 150, false);
canvas.drawPath(path,paint);

代碼2效果如下圖:

若將代碼2中的arcTo方法的參數修改為true則繪制的效果與代碼1相同。

2. reset 與 rewind

reset清除path上的內容,重置path到 path = new Path()的初始狀態。
rewind清除path上的內容,但會保留path上相關的數據結構,以高效的復用。
Detail

其它方法

  1. moveTo(float x,float y)
    移動畫筆到 (x,y) 處
  2. offset(float dx, float dy)
    平移當前path,在此path上繪制的任何圖形都會受到影響
  3. close()
    閉合當前路徑 (系統會自動從起點到終點繪制一條直線,使當前路徑閉合)
  4. reset()
    重置path,但不會重置fill-type設置
  5. rewind()
    重置path,但會保留內部數據結構
  6. set(Path src)
    設置新的Path到當前對象
  7. setLastPoint(float x,float y)
    設置當前path的終點
  8. transform(Matrix matrix)
    矩陣變換
轉自:http://ghui.me/post/2015/11/android-graphics-path/

轉載于:https://www.cnblogs.com/android-blogs/p/5702695.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372599.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372599.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372599.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2017.3.23下午

下午通過對OSPF基本原理進一步的學習,對上午學習的內容進行了復習。 轉載于:https://www.cnblogs.com/bgd140206206/p/6606192.html

編寫Eclipse插件教程–第1部分

Eclipse是三個最受歡迎的Java開發IDE之一。 其成功的原因之一是其可擴展性。 對于任何知道該怎么做并且已經做到的人來說,編寫eclipse插件都可以非常輕松快捷。 不幸的是,第一次在Eclipse中進行操作可能會非常耗時且令人沮喪。 Eclipse框架非常龐大&…

簡單Window下 Android Studio的安裝

(1)首先安裝JDK 下載JDK 本人覺得官方網站下JDK比較慢,可以直接百度JDK,(如果是64位 百度搜索記得64位) 類似于這樣的下載 安裝可以看下教程,包括環境變量的配置 如何安裝JDK (2&…

日期處理一之NSLalendar的使用

一、日期和時間模式 日期和時間格式由日期和時間模式字符串組成,在日期和時間模式字符串中未加引號的A到‘Z’和a到‘z’被解釋為模式字母,用來表示日期或時間。字符串元素,文本可以使用單引號(‘’)引起來使用。定義以…

java的使用Pair要導入什么包,第三方jar包的使用

被導入的外部類所在源文件通常要打包成jar包,java中的jar文件裝的是 .class 文件。它是一種壓縮格式和zip兼容,被稱為jar包。JDK提供的許多類,也是以jar包的形式提供的。在用的時候呢,你的文件里有很多個類,把這些類和…

十大最受歡迎的新Eclipse插件

Eclipse Marketplace仍然是發現有趣且相關的Eclipse插件的地方。 通過Eclipse Marketplace客戶端,每月成功安裝100,000多個基于Eclipse的產品。 我們提供了過去30天 以來所有時間最受歡迎的插件列表。 我認為看看過去12個月中最受歡迎的新插件會很有趣。 以下列出了…

在桌面顯示我電腦

打開Windows PowerShell(一個像是命令提示符的東西[藍底白字],但不是命令提示符),在Windows PowerShell內輸入cmd回車,當返回如下信息: Microsoft Windows [版本 6.2.9200](c) 2012 Microsoft Corporation。…

《Java技術》第二次作業計科1501趙健宇

(一)學習總結 1.使用Eclipse關聯jdk源代碼,查看String類的equals()方法 equals()方法截圖 “”比較的是地址。equals方法他同樣使用號進行內存地址的比較。但是equals方法重寫如果號比較不相等,…

注射php,UPDATE注射(mysqlphp)的兩個模式

一.測試環境:OS:Windowsxpsp2php:php4.3.10(mysql4.1.9apache1.3.33二.測試數據庫結構:-----start-----數據庫:test----------------------------------------------------------------表的結構userinfo--CREATETABLEuserinfo(groudidvarchar(12)NOTNULL…

JUnit的內置Hamcrest Core Matcher支持

在用JUnit和Hamcrest改進assertEquals的文章中,我簡要討論了Hamcrest “ 核心 ”匹配器與JUnit的現代版本“結合”在一起的情況。 在那篇文章中,我特別關注了JUnit的assertThat(T,Matcher)靜態方法與Hamcrest核心is()匹…

FormsAuthentication使用指南,實現登錄

一般情況下,在我們做訪問權限管理的時候,會把用戶的正確登錄后的基本信息保存在Session中,以后用戶每次請求頁面或接口數據的時候,拿到Session中存儲的用戶基本信息,查看比較他有沒有登錄和能否訪問當前頁面。Session的…

Java開發高性能網站需要關注的事

轉自:http://www.javabloger.com/java-development-concern-those-things/ 近期各家IT媒體舉辦的業內技術大會讓很多網站都在披露自己的技術內幕與同行們分享,大到facebook,百度,小到剛起步的網站。facebook,百度之類的…

mysql到oracle數據遷移,mysql數據遷移到oracle

mysql: utf-8字符集oracle: Al32UTF8步驟:1. 從mysql導出csv格式數據,導出時設置default_character_setgbk,否則會亂碼2.上傳至linux服務器(oracle服務器),用以下命令將windows的/r/n換成/r:sed -i "s//r//g" file3.將gbk編碼轉為u…

測試抽象類和模板方法模式

摘自Wikipedia,“模板方法定義了算法的程序框架。 子類可以覆蓋一個或多個算法步驟,以允許不同的行為,同時確保仍然遵循總體算法。” 通常,此模式由兩個或多個類組成,一個是提供模板方法(非抽象&#xff09…

LoadRunner性能測試結果計數器指標說明

LoadRunner性能測試結果計數器指標說明 轉載2015-09-23 09:57:13標簽:loadrunner計數器針對性能測試結果分析過程中,面對大量的測試數據,反而感覺無從下手分析。今天我們就Windows操作系統計數器中的個別被監控對象進行簡單的說明。 Memory: …

Elasticsearch之需要注意的問題(es和jdk版本)

(1)在使用java代碼操作es集群的時候 要保證本地使用的es的版本和集群上es的版本保持一致。 (2)保證集群中每個節點的JDK版本和es基本配置一致 這個很簡單,不多說。 (3)es集群中jdk版本不一致 …

oracle視圖查詢數據慢,8i查詢DBA_FREE_SPACE視圖極慢的問題

還是那套古老的8.1.7.4,在該系統上檢查表空間使用情況的SQL運行緩慢,其SQL如下:SELECT D.TABLESPACE_NAME,SPACE "SUM_SPACE(M)",SPACE - NVL(FREE_SPACE, 0) "USED_SPACE(M)",ROUND((1 - NVL(FREE_SPACE, 0) / SPACE) * 100, 2) &q…

bzoj 4332:JSOI2012 分零食

描述 這里是歡樂的進香河,這里是歡樂的幼兒園。 今天是2月14日,星期二。在這個特殊的日子里,老師帶著同學們歡樂地跳著,笑著。校長從幼兒園旁邊的小吃店買了大量的零食決定分給同學們。聽到這個消息,所有同學都安安靜靜…

并發–順序線程和原始線程

我不久前參與了一個項目,該項目的報告流程如下: 用戶會要求舉報 報告要求將被翻譯成較小的部分 每個零件的報告將基于零件/節的類型由報告生成器生成 組成報告的各個部分將重新組合成最終報告,并返回給用戶 我的目標是展示如何從錯誤的實…

借貸期末余額 oracle,應交稅費期末余額分別在借貸方表示什么

應交稅費是負債類科目,有時期末余額會在借方,有時會在貸方。因此,小伙伴們在實際的賬務處理工作中,一定要弄清楚兩者的含義。為了幫助大家進行有更進一步的理解,小編再次匯總了應交稅費期末余額分別在借貸方表示什么的…