1. 程式人生 > >android自定義View繪製幾何圖形

android自定義View繪製幾何圖形

1、首先說一下canvas類:

Class Overview

The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing). 

這個類相當於一個畫布,你可以在裡面畫很多東西;

我們可以把這個Canvas理解成系統提供給我們的一塊記憶體區域(但實際上它只是一套畫圖的API,真正的記憶體是下面的Bitmap),而且它還提供了一整套對這個記憶體區域進行操作的方法,所有的這些操作都是畫圖API。也就是說在這種方式下我們已經能一筆一劃或者使用Graphic來畫我們所需要的東西了,要畫什麼要顯示什麼都由我們自己控制。

這種方式根據環境還分為兩種:一種就是使用普通Viewcanvas畫圖,還有一種就是使用專門的SurfaceViewcanvas來畫圖。兩種的主要是區別就是可以在SurfaceView中定義一個專門的執行緒來完成畫圖工作,應用程式不需要等待

View的刷圖,提高效能。前面一種適合處理量比較小,幀率比較小的動畫,比如說象棋遊戲之類的;而後一種主要用在遊戲,高品質動畫方面的畫圖。

下面是Canvas類常用的方法:

drawRect(RectF rect, Paint paint) //繪製區域,引數一為RectF一個區域

drawPath(Path path, Paint paint) //繪製一個路徑,引數一為Path路徑物件

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)  //貼圖,引數一就是我們常規的Bitmap物件,引數二是源區域(這裡是bitmap),引數三是目標區域

(應該在canvas的位置和大小),引數四是Paint畫刷物件,因為用到了縮放和拉伸的可能,當原始Rect不等於目標Rect時效能將會有大幅損失。

drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //畫線,引數一起始點的x軸位置,引數二起始點的y軸位置,引數三終點的x軸水平位置,引數四y軸垂直位置,最後一個引數為Paint 畫刷物件。

drawPoint(float x, float y, Paint paint) //畫點,引數一水平x軸,引數二垂直y軸,第三個引數為Paint物件。

drawText(String text, float x, floaty, Paint paint)  //渲染文字,Canvas類除了上面的還可以描繪文字,引數一是String型別的文字,引數二x軸,引數三y軸,引數四是Paint物件。

drawOval(RectFoval,Paintpaint)//畫橢圓,引數一是掃描區域,引數二為paint物件;

drawCircle(float cx, float cy, float radius,Paintpaint)// 繪製圓,引數一是中心點的x軸,引數二是中心點的y軸,引數三是半徑,引數四是paint物件;

drawArc(RectFoval, float startAngle, float sweepAngle, boolean useCenter,Paintpaint)//畫弧,

引數一是RectF物件,一個矩形區域橢圓形的界限用於定義在形狀、大小、電弧,引數二是起始角()在電弧的開始,

引數三掃描角()開始順時針測量的,引數四是如果這是真的話,包括橢圓中心的電弧,並關閉它,如果它是假這將是一個弧線,引數五是Paint物件;

還要理解一個paint類:

Class Overview

The Paint class holds the style and color information about how to draw geometries, text and bitmaps. 

paint類擁有風格和顏色資訊如何繪製幾何學,文字和點陣圖。

Paint 代表了Canvas上的畫筆、畫刷、顏料等等;

Paint類常用方法:

setARGB(int a, int r, int g, int b) // 設定 Paint物件顏色,引數一為alpha透明值

setAlpha(int a) // 設定alpha不透明度,範圍為0~255

setAntiAlias(boolean aa) // 是否抗鋸齒

setColor(int color)  // 設定顏色,這裡Android內部定義的有Color類包含了一些常見顏色定義

setTextScaleX(float scaleX)  // 設定文字縮放倍數,1.0f為原始

setTextSize(float textSize)  // 設定字型大小

setUnderlineText(booleanunderlineText)  // 設定下劃線

2、直接看案例

看一下效果圖:

在此案例中我們用到的是自定義view;

CustomActivity.java

1. public class CustomActivity extends Activity {  

2.     @Override  

3.     public void onCreate(Bundle savedInstanceState) {  

4.         super.onCreate(savedInstanceState);  

5.         setContentView(R.layout.main);  

6.         init();  

7.     }  

8.   

9.     private void init() {  

10.         LinearLayout layout=(LinearLayout) findViewById(R.id.root);  

11.         final DrawView view=new DrawView(this);  

12.         view.setMinimumHeight(500);  

13.         view.setMinimumWidth(300);  

14.         //通知view元件重繪  

15.         view.invalidate();  

16.         layout.addView(view);  

17.           

18.     }  

19. }  


重要的類:自定義View元件要重寫View元件的onDraw(Canvase)方法,接下來是在該 Canvas上繪製大量的幾何圖形,點、直線、弧、圓、橢圓、文字、矩形、多邊形、曲線、圓角矩形,等各種形狀!

DrawView.java

1. public class DrawView extends View {  

2.   

3.     public DrawView(Context context) {  

4.         super(context);  

5.     }  

6.   

7.     @Override  

8.     protected void onDraw(Canvas canvas) {  

9.         super.onDraw(canvas);  

10.         /* 

11.          * 方法說明 drawRect 繪製矩形 drawCircle 繪製圓形 drawOval 繪製橢圓 drawPath 繪製任意多邊形 

12.          * drawLine 繪製直線 drawPoin 繪製點 

13.          */  

14.         // 建立畫筆  

15.         Paint p = new Paint();  

16.         p.setColor(Color.RED);// 設定紅色  

17.   

18.         canvas.drawText("畫圓:"1020, p);// 畫文字  

19.         canvas.drawCircle(602010, p);// 小圓  

20.         p.setAntiAlias(true);// 設定畫筆的鋸齒效果。 true是去除,大家一看效果就明白了  

21.         canvas.drawCircle(1202020, p);// 大圓  

22.   

23.         canvas.drawText("畫線及弧線:"1060, p);  

24.         p.setColor(Color.GREEN);// 設定綠色  

25.         canvas.drawLine(604010040, p);// 畫線  

26.         canvas.drawLine(1104019080, p);// 斜線  

27.         //畫笑臉弧線  

28.         p.setStyle(Paint.Style.STROKE);//設定空心  

29.         RectF oval1=new RectF(150,20,180,40);  

30.         canvas.drawArc(oval1, 180180false, p);//小弧形  

31.         oval1.set(1902022040);  

32.         canvas.drawArc(oval1, 180180false, p);//小弧形  

33.         oval1.set(1603021060);  

34.         canvas.drawArc(oval1, 0180false, p);//小弧形  

35.   

36.         canvas.drawText("畫矩形:"1080, p);  

37.         p.setColor(Color.GRAY);// 設定灰色  

38.         p.setStyle(Paint.Style.FILL);//設定填滿  

39.         canvas.drawRect(60608080, p);// 正方形  

40.         canvas.drawRect(6090160100, p);// 長方形  

41.   

42.         canvas.drawText("畫扇形和橢圓:"10120, p);  

43.         /* 設定漸變色這個正方形的顏色是改變的 */  

44.         Shader mShader = new LinearGradient(00100100,  

45.                 new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,  

46.                         Color.LTGRAY }, null, Shader.TileMode.REPEAT); // 一個材質,打造出一個線性梯度沿著一條線。  

47.         p.setShader(mShader);  

48.         // p.setColor(Color.BLUE);  

49.         RectF oval2 = new RectF(60100200240);// 設定個新的長方形,掃描測量  

50.         canvas.drawArc(oval2, 200130true, p);  

51.         // 畫弧,第一個引數是RectF:該類是第二個引數是角度的開始,第三個引數是多少度,第四個引數是真的時候畫扇形,是假的時候畫弧線  

52.         //畫橢圓,把oval改一下  

53.         oval2.set(210,100,250,130);  

54.         canvas.drawOval(oval2, p);  

55.   

56.         canvas.drawText("畫三角形:"10200, p);  

57.         // 繪製這個三角形,你可以繪製任意多邊形  

58.         Path path = new Path();  

59.         path.moveTo(80200);// 此點為多邊形的起點  

60.         path.lineTo(120250);  

61.         path.lineTo(80250);  

62.         path.close(); // 使這些點構成封閉的多邊形  

63.         canvas.drawPath(path, p);  

64.   

65.         // 你可以繪製很多任意多邊形,比如下面畫六連形  

66.         p.reset();//重置  

67.         p.setColor(Color.LTGRAY);  

68.         p.setStyle(Paint.Style.STROKE);//設定空心  

69.         Path path1=new Path();  

70.         path1.moveTo(180200);  

71.         path1.lineTo(200200);  

72.         path1.lineTo(210210);  

73.         path1.lineTo(200220);  

74.         path1.lineTo(180220);  

75.         path1.lineTo(170210);  

76.         path1.close();//封閉  

77.         canvas.drawPath(path1, p);  

78.         /* 

79.          * Path類封裝複合(多輪廓幾何圖形的路徑 

80.          * 由直線段*、二次曲線,和三次方曲線,也可畫以油畫。drawPath(路徑、油漆),要麼已填充的或撫摸 

81.          * (基於油漆的風格),或者可以用於剪斷或畫畫的文字在路徑。 

82.          */  

83.           

84.         //畫圓角矩形  

85.         p.setStyle(Paint.Style.FILL);//充滿  

86.         p.setColor(Color.LTGRAY);  

87.         p.setAntiAlias(true);// 設定畫筆的鋸齒效果  

88.         canvas.drawText("畫圓角矩形:"10260, p);  

89.         RectF oval3 = new RectF(80260200300);// 設定個新的長方形  

90.         canvas.drawRoundRect(oval3, 2015, p);//第二個引數是x半徑,第三個引數是y半徑  

91.           

92.         //畫貝塞爾曲線  

93.         canvas.drawText("畫貝塞爾曲線:"10310, p);  

94.         p.reset();  

95.         p.setStyle(Paint.Style.STROKE);  

96.         p.setColor(Color.GREEN);  

97.         Path path2=new Path();  

98.         path2.moveTo(100320);//設定Path的起點  

99.         path2.quadTo(150310170400); //設定貝塞爾曲線的控制點座標和終點座標  

100.         canvas.drawPath(path2, p);//畫出貝塞爾曲線  

101.           

102.         //畫點  

103.         p.setStyle(Paint.Style.FILL);  

104.         canvas.drawText("畫點:"10390, p);  

105.         canvas.drawPoint(60390, p);//畫一個點  

106.         canvas.drawPoints(new float[]{60,400,65,400,70,400}, p);//畫多個點  

107.           

108.         //畫圖片,就是貼圖  

109.         Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);  

110.         canvas.drawBitmap(bitmap, 250,360, p);  

111.     }  

112. }  

一、Canvas類android.graphics.Canvas 

Canvas類好比手機中的畫紙,我們可以在Canvas上畫圖形或者影象。一般我們用android來繪畫的時候,需要四個組成部分: 1、點陣圖:包含畫素 2、Canvas畫板:包含繪畫內容,寫入點陣圖 3、初始圖形:如Rect、Bitmap、text等 4、Paint:用來描述上面初始圖形的顏色和型別等 Canvas類提供了三個構造方法: Public Canvas();構造一個預設無參的Canvas物件 Public Canvas(Bitmapbitmap);根據一個Bitmap構造一個Canvas物件 Public Canvas(GL gl);根據一個GL來構造一個物件 下面我們來了解一下Canvas類提供的方法: 在Canvas類提供的方法中比較多經常用的是以draw開頭的方法,draw開頭的方法很容易理解就是向畫板中畫圖形,比如可以向Canvas中畫點陣圖,給圖形填充顏色等。 

二、Paint類android.graphics.Paint 

Paint類包含有用來畫幾何圖形、文字、點陣圖的型別和顏色等資訊,如果把Canvas類看作是畫板,那我們可以把Paint類看做是畫筆,可以根據需要畫出不同顏色和樣式的圖形、文字等內容。 Paint類有三個構造方法: Public Paint()構造一個預設的Paint物件 Public Paint(int flags);根據指定的flags來構造一個Paint物件,建立之後可以用 setFlags()方法來更改 Public Paint(Paint paint)根據指定的paint物件來構造一個Paint物件 Paint類提供了很多方法來設定和獲取Paint物件的屬性,比如: public int getColor ()獲得Paint物件的顏色值 public ColorFilter getColorFilter ()獲得顏色過濾器 public float getTextSize ()獲得字型大小數值 public void setStyle (Paint.Stylestyle)設定paint的型別 

三  Color類android.graphics.Color 

此類 定義了一些方法來建立和轉換顏色值。顏色被表示為封裝的數值,這個數值由四個位元組組成,分別是:alpha、red、green、blue,這些值是非自 左乘的,也就是說任何透明性只儲存在alpha部分,而不是在顏色組成部分。每一部分按照如下的順序儲存:(alpha<<24)| (red<<16)|<green<<8)|blue.每一部分的取值範圍在0-255之間,0意味著這部分不起作 用,255表示100%的起作用。因此不透明的黑色應該是0xFF000000,不透明的白色應該是0xFFFFFFFF 。 Color類提供了12個常量值來代表不同的顏色值,我們在開發工程中可以直接呼叫這些常量值來設定我們所要修飾的文字、圖形等物件。 Color類提供了一個無參的構造方法Color() Color類提供了一些方法來進行顏色值的建立和轉換如下: 其中三個方法是用來返回一個顏色常量值的紅綠藍分色,數值分別在0-255之間,如下: Public staticred(int color); Public static green(int color); Public static blue(int color); 其中Public static int rgb(int red,int green,int blue);輸入紅綠藍三色,返回一個RGB顏色值。 下面幾個方法大家可以參考Android API來了解: Public static int HSVToColor(int alpha,float[] hsv); Public static int HSVToColor(float[] hsv); Public static void RGBToHSV(int red,int green,int blue,float[] hsv); Public static int alpha(int color); Public static int argb(intalpha,intred,intgreen,int blue); Public static colorToHSV(int color,float[] hsv); Public static parseColor(String colorString); 

四.Typeface類android.graphics.Typeface 

Typeface類定義字型和字型內在的型別。這個類被用在畫筆Paint設定的時候,比如用textSize,textSkewX和textScale設定來指定text在畫的時候如何來顯示和測量。 

Typeface 提供了一些常量值來表示自身的一些屬性,比如BOLD,BOLD_ITALIC,ITALIC等,開發者可以用 defaultFrOPhone SDNtyle(int style)獲得內在的Typeface物件。讀者可以參考詳細的API文件再這裡就不再贅述了。 

下面我們來看一下Typeface的主要方法。 

Typeface類沒有構造方法,通常如果一個類沒有構造函式就無法通過構造來生成一個物件實體,此時一般會有特定的靜態方法來取得這個類的實體。Typeface就提供了四個靜態方法間接來得到Typeface實體分別如下: 

Public static Typeface create(Typeface family,intstyle); 

此方法返回一個與已經存在的Typeface字形體系相匹配且型別是指定型別的Typeface。如果你想得到一個與已經存在的Typeface字形體系 相類似,但是樣式不一樣的Typeface時可以呼叫此方法。其中family引數可以為null,如果為空則表示從預設的Typeface字形體系中選 擇。 

Public static Typefaxe create(String familyname,int style); 

此方法通過給定的字形體系的名稱familyname和指定的型別返回一個Typeface物件。如果給定字形體系的名稱為null,我們可以通過getStyle()方法來獲得返回Typeface物件的真正的屬性。 

Public static Typeface createFromAsset(AssetManager mgr,String path); 

此方法通過規定的字型資料來返回一個Typeface物件。第一個引數為資源管理器,第二個引數是指定字型型別。 

Public static Typeface defaultFrOPhone SDNtyle(intstyle);此方法返回一個指定型別的Typeface物件 

Typeface還提供了另外三個方法: 

Public int getStyle();此方法返回Typeface內在的型別屬性 

Public final Boolean isBold();如果getStyle()有BOLD位組將返回true 

Public final Boolean isItalic();如果getStyle()有ITALIC位組將返回true 

五、Path類android.graphics.Path 

Path類(一組區域)的描畫,類囊括多種幾何圖形比如直線線段、二次曲線、三次曲線等, 

呼叫Canvas.drawPath()方法可以將Path以所定義的paint的方式來畫到畫板上或者填出圖形,也可以用paint所指定方式來畫圖形。 

六、RectF類android.graphics.RectF和Rect類android.graphics.Rect 

RectF 這個類包含一個矩形的四個單精度浮點座標。矩形通過上下左右4個邊的座標來表示一個矩形。這些座標值屬性可以被直接訪問,用width()和 height()方法可以獲取矩形的寬和高。注意:大多數方法不會檢查這些座標分類是否錯誤(也就是left<=right和top& lt;=bottom). 

RectF一共有四個構造方法: 

RectF()構造一個無參的矩形 

RectF(float left,float top,float right,float bottom)構造一個指定了4個引數的矩形 

RectF(Rect F r)根據指定的RectF物件來構造一個RectF物件(物件的左邊座標不變) 

RectF(Rect r)根據給定的Rect物件來構造一個RectF物件 

RectF提供了很多方法,下面介紹幾個方法: 

Public Boolean contain(RectF r);判斷一個矩形是否在此矩形內,如果在這個矩形內或者和這個矩形等價則返回true,同樣類似的方法還有public Boolean contain(float left,float top,float right,float bottom)和public Boolean contain(float x,float y)。 

Public void union(float x,float y)更新這個矩形,使它包含矩形自己和(x,y)這個點。 

RectF類提供的方法都比較簡單,容易理解,再此就不再一一贅述 

Android.graphics.Rect類,這個類同android.graphics.RectF很相似,不同的地方是Rect類的座標是用整形表示的,而RectF的座標是用單精度浮點型表示的。這裡大家一定要注意 啊。 

七、Point類android.graphics.Point 

   這個類從字面意思就可以看出它跟點有關係,是點的一個物件類。 

這個類有兩個屬性,分別是:X座標和y座標。 

構造函式有三個:Point(),Point(int x,int y),Point(Point p) 

主要方法有: 

Public void set(x,y);重新設定一下x,y的座標 

Public final void offset(int dx,int dy);給座標一個補償值,值可以使正的也可以是負的。 

Public final void negate();否定座標值。 

Point類和android.graphics.PointF類似,不同點是前者座標值的型別是int型,而後者的座標值是float型。除此之外PointF類多加了幾個方法,比如: 

Public final float length();返回(0,0)點到該點的距離。 

Public static float length(float x,float y);返回(0,0)點到(x,y)點的距離。

引數

left

FLOAT

矩形左下點的 座標。預設值為 0.f

top

FLOAT

矩形左下角的 座標。預設值為 0.f

right

FLOAT

矩形右下點的 座標。預設值為 0.f

bottom

FLOAT

矩形右上角 座標。預設值為 0.f