編輯:關於Android編程
馬上要到五一了,提前祝賀大家五一快樂。
今天的主角是路勁,這個詞給我的第一印象就是那種彎彎的小路,屆時讓我想起了小時候的曲徑通幽處
,反正我是忘記了下一句是什麼。言歸正傳,Android
中的Path
又有哪一些呢,以及它們的常用方法。
使用Path
不僅可以繪制簡單的圖形(如圓形,矩形,直線等),也可以繪制復雜一些的圖形(如正多邊形,五角星等),還有繪制裁剪和繪制文本都會用到Path
。由於方法比較多,我這裡分組來講下。
先創建畫筆:
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
paint.setColor(Color.parseColor("#FF0000"));
注意paint.setStyle(Paint.Style.FILL);
,設置畫筆為實心。一些線條將在畫布上看不見。
首先我們來看看lineTo
,如果你直接moveTo
將看不出效果。
Path path = new Path();
path.lineTo(200,200);
path.lineTo(400,0);
canvas.drawPath(path,paint);
為了方便大家好觀察坐標的變化,我在屏幕上畫出了網格,每塊網格的寬高都是100。由於第一次之前沒有過操作,所以默認點就是原點(屏幕左上角),第一次lineTo
就是坐標原點到(200,200)之間的直線。第二次lineTo
就是上一次結束點位置(200,200)到(400,0)點之間的直線。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoNCBpZD0="2moveto-和setlastpoint">2、moveTo 和setLastPoint
方法預覽:
moveTo(float x, float y)
setLastPoint(float dx, float dy)
這兩個方法在作用上有相似之處,卻是兩個不同的東西,具體參考下表:
來看看下面的例子:
Path path = new Path();
path.lineTo(200, 200);
path.moveTo(300,300);
path.lineTo(400, 0);
canvas.drawPath(path, paint);
效果圖:
Path path = new Path();
path.lineTo(200, 200);
path.setLastPoint(300,100);
path.lineTo(400, 0);
canvas.drawPath(path, paint);
效果圖:
當我們繪制線條之前,調用moveTo
和 setLastPoint
效果是一樣的,都是對坐標原點(0,0)進行操作。setLastPoint
是重置上一次操作的最後一點,在執行完第一次lineTo
的時候,最後一個點就是(200,200),setLastPoint
更改(200,200)為(300,100),所以在執行的時候就是(300,100)到(400, 0)之間的連線了。
方法預覽
public void close()
close
方法連接最後一個點和最初一個點(如果兩個點不重合)形成一個閉合的圖形。
path.moveTo(100,100);
path.lineTo(500,100);
path.lineTo(300,400);
path.close();
canvas.drawPath(path, paint);
效果圖:
上圖中可以看到lineTo(500,100)
直線和lineTo(300,400)
直線,而close
方法就是連接(300,400),(100,100)兩點,形成一個閉合的區域。
注意:close的作用的封閉路徑,如果連接最後一個點和最初一個點任然無法形成閉合的區域,那麼close什麼也不做。
二次貝塞爾曲線以及三次貝塞爾曲線。
方法預覽
public void quadTo(float x1, float y1, float x2, float y2)
quadTo
方法其中 (x1,y1) 為控制點,(x2,y2)為結束點。
path.moveTo(100,400);
path.quadTo(300, 100, 400, 400);
canvas.drawPath(path, paint);
效果圖:
方法預覽:
public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
cubicTo
方法比quadTo
方法多了一個點坐標,那麼其中(x1,y1) 為控制點,(x2,y2)為控制點,(x3,y3) 為結束點。
path.moveTo(100, 400);
path.cubicTo(100, 400, 300, 100, 400, 400);
canvas.drawPath(path, paint);
繪制的圖形和上面的quadTo
繪制的圖形是一樣的。我們去掉moveTo
來看看運行的效果圖:
如果你想了解貝塞爾曲線公式,請鏈接這裡
主要是向Path
中添加基本圖形以及區分addArc
和arcTo
方法預覽:
//圓形
addCircle(float x, float y, float radius, Path.Direction dir)
//橢圓
addOval(RectF oval, Path.Direction dir)
addOval(float left, float top, float right, float bottom, Path.Direction dir)
//矩形
addRect(RectF rect, Path.Direction dir)
addRect(float left, float top, float right, float bottom, Path.Direction dir)
//圓角矩形
addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir)
addRoundRect(RectF rect, float[] radii, Path.Direction dir)
addRoundRect(float left, float top, float right, float bottom, float[] radii, Path.Direction dir)
我們仔細觀察上面的方法,在最後都有一個Path.Direction
,這是個什麼東東呢?Direction
的意思是方向,指導,趨勢。點進去跟一下你會發現Direction
是一個枚舉類型(Enum)分別有CW(順時針),CCW(逆時針)兩個常量。那麼它的作用主要有以下兩點:
我們先來看看閉合順序的問題,添加一個矩形看看:
path.addRect(100, 200, 500, 400, Path.Direction.CW);
canvas.drawPath(path, paint);
我將上面的代碼CW
改成CCW
再運行一次,結果一模一樣,尼瑪區別在哪裡啊。稍安勿躁,想看到區別就要用到setLastPoint
(重置最後一個點的坐標)。我們來這樣變變代碼:
path.addRect(100, 200, 500, 400, Path.Direction.CW);
path.setLastPoint(200,400);
canvas.drawPath(path, paint);
效果立馬現行:
為什麼圖形會發生奇怪的變化呢。我們先來分析一下,繪制一個矩形至少需要對角線的兩個點,根據這兩個點計算出四條邊然後把四條邊按照順序連接起來。上圖的起始坐標是(100,200)按著順時針的方向連接(500,200),(500,400),(100,400)最後連接(100,200)形成一個矩形。setLastPoint
是重置上一個操作點坐標及改變(100,400)為(200,400),所以出現了上圖的效果。
接下來我們看看逆時針的情況:
path.addRect(100, 200, 500, 400, Path.Direction.CCW);
path.setLastPoint(400,300);
canvas.drawPath(path, paint);
效果圖:
我們理清楚了閉合的問題,相交問題與設置填充模式有關。
我以addCircle
方法來講解添加圖形,並不會逐一講解。
path.addCircle(300,300,200, Path.Direction.CW);
canvas.drawPath(path, paint);
繪制圓形,(300,300)點表示圓心坐標,200 表示半徑長度。
方法預覽:
public void addPath(Path src)
public void addPath(Path src, float dx, float dy)
public void addPath(Path src, Matrix matrix)
addPath方法就是將兩個路徑合並到一起。第二個方法的dx,dy
指的是偏移量,第三個方法是添加到當前path之前先使用Matrix進行變換。來看看下面例子:
Path path = new Path();
path.addRect(100,100,400,300, Path.Direction.CW);
Path src=new Path();
src.addCircle(300,300,100, Path.Direction.CW);
path.addPath(src,0,100);
canvas.drawPath(path, paint);
效果圖:
方法預覽:
addArc(RectF oval, float startAngle, float sweepAngle)
addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)
arcTo(RectF oval, float startAngle, float sweepAngle)
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)
從方法名字上面看,這兩個方法都是與圓弧有關,那麼他們之間肯定是有區別的:
startAngle
表示開始圓弧度數(0度與X軸方向對齊,順時針移動,弧度增大)。
注意:sweepAngle
表示運動了多少弧度,並不是結束弧度。
forceMoveTo表示“是否強制使用moveTo”,也就是說是否使用moveTo將上一次操作點移動到圓弧的起點坐標。默認是false。
示例:
path.lineTo(200, 200);
RectF rectF = new RectF(100, 100, 400, 400);
path.arcTo(rectF, 0, 270, true);
// path.addArc(rectF,0,270);和上面一句等價
canvas.drawPath(path, paint);
效果圖:
我們把 path.arcTo(rectF, 0, 270, true);
改成 path.arcTo(rectF, 0, 270, false);
,來看看效果圖:
從上面兩張圖可以看出明顯的變化。
判斷path中是否包含內容。
Path path = new Path();
Log.e("-----","----"+path.isEmpty());//-----: ----true
path.lineTo(100,100);
Log.e("-----","----"+path.isEmpty());//-----: ----false
canvas.drawPath(path, paint);
方法預覽:
isRect(RectF rect)
判斷path是否是一個矩形,如果是一個矩形的話,會將矩形的信息存放進參數rect中。
Path path = new Path();
RectF rectF = new RectF();
rectF.left = 100;
rectF.top = 100;
rectF.right = 400;
rectF.bottom = 300;
path.addRect(rectF, Path.Direction.CW);
boolean isRect = path.isRect(rectF);
Log.e("-----","------"+isRect);//-----: ------true
方法預覽:
public void set(Path src)
將新的path賦值到現有path。相當於運算符中的“=”,如a=b
,把b
賦值給a
還是一起來看個例子:
Path path = new Path();
path.addRect(100,100,400,300, Path.Direction.CW);
Path src=new Path();
src.addCircle(300,200,100, Path.Direction.CW);
path.set(src);
canvas.drawPath(path, paint);
效果圖:
方法預覽:
public void offset(float dx, float dy)
public void offset(float dx, float dy, Path dst)
這個方法就是對Path
進行一段平移,正方向和X軸,Y軸方向一致(如果dx為正數則向右平移,反之向左平移;如果dy為正則向下平移,反之向上平移)。我們看到第二個方法多了一個dst
,這個又是一個什麼玩意呢,其實參數das是存儲平移後的path的。
用例子來說明一下:
Path path = new Path();
path.addCircle(300, 200, 100, Path.Direction.CW);
Path dst = new Path();
dst.addCircle(500, 200, 200, Path.Direction.CW);
path.offset(-100, 100, dst);
canvas.drawPath(path, paint);
效果圖:
從運行效果圖可以看出,雖然我們在dst中添加了一個圓形,但是並沒有表現出來,所以,當dst中存在內容時,dst中原有的內容會被清空,而存放平移後的path。
方法預覽:
public void setFillType(Path.FillType ft)
public Path.FillType getFillType()
setFillType
方法中的參數Path.FillType
為枚舉類型:
path所在區域
path所在區域
path所在區域
WINDING
Path path = new Path();
path.addCircle(300,200,100, Path.Direction.CW);
path.addCircle(200,200,100, Path.Direction.CW);
path.setFillType(Path.FillType.WINDING);
canvas.drawPath(path, paint);
效果圖:
EVEN_ODD
代碼我就不貼了,直接上圖(上mis):
INVERSE_WINDING
INVERSE_EVEN_ODD
是否是逆填充模式:WINDING 和 EVEN_ODD 返回false;
INVERSE_WINDING 和 INVERSE_EVEN_ODD 返回true;
切換相反的填充模式,如果填充模式為WINDING
則填充模式為INVERSE_WINDING
,反之為WINDING
模式;如果填充模式為EVEN_ODD
則填充模式為INVERSE_EVEN_ODD
,反之為EVEN_ODD
模式。
舉個例子:
Path path = new Path();
path.addCircle(300,200,100, Path.Direction.CW);
path.addCircle(200,200,100, Path.Direction.CW);
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
path.toggleInverseFillType();
canvas.drawPath(path, paint);
效果圖和上面EVEN_ODD
模式一模一樣。
就寫到這裡,文中有什麼寫錯,寫偏的請給我留言。
什麼是ServiceService是Android 的四大組件之一,主要處理一些耗時的後台操作邏輯,或者輪詢操作等需要長期在後台運行的任務。甚至在程序退出之後,可以讓Se
現在的微信推送已為最新版6.2。不知你是否注意到新版本微信中有一個新功能——收錢。微信這款功能能夠及時的幫助大家還款和收款,只要掃一
API IntroductionContent providers are one of the primary building blocks(構件) of Andro
Activity數據傳遞之基本數據類型在這篇文章中,我寫了通過putExtra()方法在activity之間傳遞基本數據類型但是如果我們想傳遞對象還用這種方法會發現報錯,