Android中自定義檢視View
標籤:
前言
好長時間沒寫blog了,心裡感覺有點空蕩蕩的,今天有時間就來寫一個關於自定義檢視的的blog吧。關於這篇blog,網上已經有很多案例了,其實沒什麼難度的。但是我們在開發的過程中有時候會用到一些自定義的View以達到我們所需要的效果。其實網上的很多案例我們看完之後,發現這部分沒什麼難度的,我總結了兩點:
1、準備紙和筆,計算座標
2、在onDraw方法中開始畫圖,invalidate方法重新整理,onTouchEvent方法監聽觸控事件
對於繪圖相關的知識,之前在弄JavaSE相關的知識的時候,寫過俄羅斯方塊,也是用畫筆繪製的,然後在重新整理。原理都一樣的。
在這個過程中,我們需要了解兩個很重要的東西:
畫筆:Paint
畫布:Canvas
引用資料
講解內容
那麼下面我們就開始來介紹相關的內容了。我主要分一下步驟來講解一下:
1、介紹Android中的Paint和Canvas的概念和使用方法
2、介紹Android中重要的概念渲染物件Shader
3、自定義一個LabelView(和Android中的TextView差不多)
4、自定義漸變的圓形和長條的SeekBar
5、自定義顏色選擇器
6、自定義閃爍的TextView
7、實現360手機衛士中的流量監控的折線圖
那麼我們也知道今天的文章內容應該會很多,所以大家要有耐心的看完。這篇文章如果看懂了,也耐心的看完了,相信對自定義View的相關知識瞭解的應該也差不多了,自己在開發的過程中實現自己想要的簡單的View應該是沒有問題的。
內容講解
下面開始正式介紹內容
一、介紹Android中的Paint和Canvas的概念和使用方法
Android中的Paint和Canvas的概念是很簡單的,就是我們用畫筆在畫布上進行繪製沒什麼難度的,我們只要拿到畫筆Paint和畫布Canvas物件就可以進行操作了。當然Canvas物件提供了很多繪製圖形的方法,下面來看一下程式碼吧:
執行一下看效果圖:package com.example.drawpathdemo; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; public class DrawView extends View { public DrawView(Context context) { super(context); } public DrawView(Context context, AttributeSet attributeSet) { super(context, attributeSet); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /* * 方法 說明 drawRect 繪製矩形 drawCircle 繪製圓形 drawOval 繪製橢圓 drawPath 繪製任意多邊形 * drawLine 繪製直線 drawPoin 繪製點 */ // 建立畫筆 Paint p = new Paint(); p.setColor(Color.RED);// 設定紅色 canvas.drawText("畫圓:", 10, 20, p);// 畫文字 canvas.drawCircle(60, 20, 10, p);// 小圓 p.setAntiAlias(true);// 設定畫筆的鋸齒效果。 true是去除,大家一看效果就明白了 canvas.drawCircle(120, 20, 20, p);// 大圓 canvas.drawText("畫線及弧線:", 10, 60, p); p.setColor(Color.GREEN);// 設定綠色 canvas.drawLine(60, 40, 100, 40, p);// 畫線 canvas.drawLine(110, 40, 190, 80, p);// 斜線 //畫笑臉弧線 p.setStyle(Paint.Style.STROKE);//設定空心 RectF oval1=new RectF(150,20,180,40); canvas.drawArc(oval1, 180, 180, false, p);//小弧形 oval1.set(190, 20, 220, 40); canvas.drawArc(oval1, 180, 180, false, p);//小弧形 oval1.set(160, 30, 210, 60); canvas.drawArc(oval1, 0, 180, false, p);//小弧形 canvas.drawText("畫矩形:", 10, 80, p); p.setColor(Color.GRAY);// 設定灰色 p.setStyle(Paint.Style.FILL);//設定填滿 canvas.drawRect(60, 60, 80, 80, p);// 正方形 canvas.drawRect(60, 90, 160, 100, p);// 長方形 canvas.drawText("畫扇形和橢圓:", 10, 120, p); /* 設定漸變色 這個正方形的顏色是改變的 */ Shader mShader = new LinearGradient(0, 0, 100, 100, new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.LTGRAY }, null, Shader.TileMode.REPEAT); // 一個材質,打造出一個線性梯度沿著一條線。 p.setShader(mShader); // p.setColor(Color.BLUE); RectF oval2 = new RectF(60, 100, 200, 240);// 設定個新的長方形,掃描測量 canvas.drawArc(oval2, 200, 130, true, p); // 畫弧,第一個引數是RectF:該類是第二個引數是角度的開始,第三個引數是多少度,第四個引數是真的時候畫扇形,是假的時候畫弧線 //畫橢圓,把oval改一下 oval2.set(210,100,250,130); canvas.drawOval(oval2, p); canvas.drawText("畫三角形:", 10, 200, p); // 繪製這個三角形,你可以繪製任意多邊形 Path path = new Path(); path.moveTo(80, 200);// 此點為多邊形的起點 path.lineTo(120, 250); path.lineTo(80, 250); path.close(); // 使這些點構成封閉的多邊形 canvas.drawPath(path, p); // 你可以繪製很多任意多邊形,比如下面畫六連形 p.reset();//重置 p.setColor(Color.LTGRAY); p.setStyle(Paint.Style.STROKE);//設定空心 Path path1=new Path(); path1.moveTo(180, 200); path1.lineTo(200, 200); path1.lineTo(210, 210); path1.lineTo(200, 220); path1.lineTo(180, 220); path1.lineTo(170, 210); path1.close();//封閉 canvas.drawPath(path1, p); /* * Path類封裝複合(多輪廓幾何圖形的路徑 * 由直線段*、二次曲線,和三次方曲線,也可畫以油畫。drawPath(路徑、油漆),要麼已填充的或撫摸 * (基於油漆的風格),或者可以用於剪斷或畫畫的文字在路徑。 */ //畫圓角矩形 p.setStyle(Paint.Style.FILL);//充滿 p.setColor(Color.LTGRAY); p.setAntiAlias(true);// 設定畫筆的鋸齒效果 canvas.drawText("畫圓角矩形:", 10, 260, p); RectF oval3 = new RectF(80, 260, 200, 300);// 設定個新的長方形 canvas.drawRoundRect(oval3, 20, 15, p);//第二個引數是x半徑,第三個引數是y半徑 //畫貝塞爾曲線 canvas.drawText("畫貝塞爾曲線:", 10, 310, p); p.reset(); p.setStyle(Paint.Style.STROKE); p.setColor(Color.GREEN); Path path2=new Path(); path2.moveTo(100, 320);//設定Path的起點 path2.quadTo(150, 310, 170, 400); //設定貝塞爾曲線的控制點座標和終點座標 canvas.drawPath(path2, p);//畫出貝塞爾曲線 //畫點 p.setStyle(Paint.Style.FILL); canvas.drawText("畫點:", 10, 390, p); canvas.drawPoint(60, 390, p);//畫一個點 canvas.drawPoints(new float[]{60,400,65,400,70,400}, p);//畫多個點 //畫圖片,就是貼圖 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); canvas.drawBitmap(bitmap, 250,360, p); } }
1、Path物件
在程式碼中我們看到了我們新建了一個Paint畫筆物件,對於畫筆物件,它有很多設定屬性的:
void setARGB(int a, int r, int g, int b) 設定Paint物件顏色,引數一為alpha透明通道
void setAlpha(int a) 設定alpha不透明度,範圍為0~255
void setAntiAlias(boolean aa) //是否抗鋸齒,預設值是false
void setColor(int color) //設定顏色,這裡Android內部定義的有Color類包含了一些常見顏色定義
void setFakeBoldText(boolean fakeBoldText) //設定偽粗體文字
void setLinearText(boolean linearText) //設定線性文字
PathEffect setPathEffect(PathEffect effect) //設定路徑效果
Rasterizer setRasterizer(Rasterizer rasterizer) //設定光柵化
Shader setShader(Shader shader) //設定陰影 ,我們在後面會詳細說一下Shader物件的
void setTextAlign(Paint.Align align) //設定文字對齊
void setTextScaleX(float scaleX) //設定文字縮放倍數,1.0f為原始
void setTextSize(float textSize) //設定字型大小
Typeface setTypeface(Typeface typeface) //設定字型,Typeface包含了字型的型別,粗細,還有傾斜、顏色等
注:
Paint mp = new paint();
mp.setTypeface(Typeface.DEFAULT_BOLD)
常用的字型型別名稱還有:
Typeface.DEFAULT //常規字型型別
Typeface.DEFAULT_BOLD //黑體字型型別
Typeface.MONOSPACE //等寬字型型別
Typeface.SANS_SERIF //sans serif字型型別
Typeface.SERIF //serif字型型別
除了字型型別設定之外,還可以為字型型別設定字型風格,如設定粗體:
Paint mp = new Paint();
Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
p.setTypeface( font );
常用的字型風格名稱還有:
Typeface.BOLD //粗體
Typeface.BOLD_ITALIC //粗斜體
Typeface.ITALIC //斜體
Typeface.NORMAL //常規
void setUnderlineText(boolean underlineText) //設定下劃線
void setStyle(Style style) //設定畫筆樣式
注:
常用的樣式
Paint.Style.FILL
Paint.Style.STROKE
Paint.Style.FILL_AND_STROKE
這裡的FILL和STROKE兩種方式用的最多,他們的區別也很好理解的,FILL就是填充的意思,STROKE就是空心的意思,只有圖形的輪廓形狀,內部是空的。
void setStrokeWidth(float width) //在畫筆的樣式為STROKE的時候,圖形的輪廓寬度
2、Canvas物件
對於畫布物件Canvas我們是從onDraw方法中獲取到的,所以這裡我們就可以看不來了,我們在自定義檢視的時候都會繼承View類,然後在他的onDraw方法中拿到Canvas物件,進行各種繪製了。下面就來一一看一下各種繪製的方法吧:
首先來看一下如何建立一個畫筆物件:
Paint p = new Paint();
p.setColor(Color.RED);// 設定紅色
我們可以設定畫筆的顏色,當然還有其他的方法,我們可以設定畫筆的粗細,是否有鋸齒等,後面會說道。1)、畫圓(drawCircle)
我們想一下,如果畫出一個圓形的話需要哪些要素,學過幾何的同學都知道:圓形座標+半徑 就可以確定一個圓形了
canvas.drawCircle(120, 20, 20, p);
引數一:圓心的x座標
引數二:圓心的y座標
引數三:圓的半徑
引數四:畫筆物件
還有一個這裡我們設定了畫筆是否有鋸齒:
p.setAntiAlias(true);// 設定畫筆的鋸齒效果。 true是去除,大家一看效果就明白了
關於這個鋸齒,其實很好理解,就是如果沒有鋸齒效果,那麼畫出來的圓形就很光滑,有鋸齒看上去的圓形很粗糙的。但是預設情況下,畫筆是有鋸齒的。之所以這樣,是因為在沒有鋸齒效果的情況下,繪製圖形效率會比有鋸齒效果低,所以系統考慮了效率問題,就把預設值設定成有鋸齒了,我們在實際繪圖過程中需要衡量一下的。2)、畫直線(drawLine)
我們想一下,如果畫出一個直線的話需要哪些要素,起始點座標+終點座標 就可以確定一條直線了
canvas.drawLine(60, 40, 100, 40, p);// 畫線
引數一:起始點的x座標
引數二:起始點的y座標
引數三:終點的x座標
引數四:終點的y座標
引數五:畫筆物件
3)、畫橢圓(drawOval)
我們想一下,如果畫出橢圓的話需要哪些要素,長軸+短軸的長度
RectF oval1=new RectF(150,20,180,40);
canvas.drawOval(oval2, p);
引數一:橢圓的外接矩形
引數二:畫筆物件
這裡先來說一下RectF的相關知識吧:在繪圖中這個物件是十分重要的,它表示的是一個矩形,它有四個引數:
left,top,right,bottom
這四個值是相對於裝置螢幕的起始點開始的。
<span style="padding: 0px; font-size: 14px;">RectF oval1=new RectF(150,20,180,40);</span>
比如上面的這個矩形,說白了就是這樣:
矩形的左上角的座標是:(150,20)
矩形的右下角的座標是:(180,30)
那麼我們就知道這個矩形的寬是:180-150=30;高是:40-20=20
其實還有與RectF物件對應的還有一個物件:Rect,它也是四個引數,和RectF唯一的區別就是,Rect中的引數是float型別的,RectF中的引數是int型別的
那麼一個矩形就可以確定一個橢圓的,這個矩形就是和這個橢圓外接:
那麼橢圓的長軸就是矩形的寬,短軸就是矩形的高
這樣就可以確定一個橢圓了,那麼如果我們想畫一個圓形的話用這種方式也是可以的,只要把RectF設定成正方形就可以了。
4)、畫弧線/畫扇形(drawArc)
我們想一下,如果畫出一個弧線的話需要哪些要素,起始的弧度+弧線的弧度+外圍的矩形大小
這個和上面畫橢圓很相似的,就相當於在他的基礎上多了其實弧度+弧線的弧度
p.setStyle(Paint.Style.STROKE);//設定空心
RectF oval1=new RectF(150,20,180,40);
canvas.drawArc(oval1, 180, 180, false, p);//小弧形
引數一:外接弧形的矩形
引數二:弧線開始的弧度
引數三:弧線的弧度
引數四:是一個boolean型別的引數:true的時候畫扇形,是false的時候畫弧線
引數五:畫筆物件
5)、畫矩形(drawRect)
RectF oval1=new RectF(150,20,180,40);
canvas.drawRect(oval1, p);
引數一:矩形物件
引數二:畫筆物件
6)、畫圓角矩形(drawRoundRect)
RectF oval3 = new RectF(80, 260, 200, 300);// 設定個新的長方形
canvas.drawRoundRect(oval3, 20, 15, p);//第二個引數是x半徑,第三個引數是y半徑
引數一:矩形大小
引數二:圓角的x半徑(橢圓的長軸的一半)
引數三:圓角的y半徑(橢圓的短軸的一半)
引數四:畫筆物件
其實這個和正常的矩形不一樣的是:在四個角是有弧度的,那麼弧度的話,就會想到橢圓了,我們在上面說道橢圓的幾個要素:長軸和短軸,那麼這裡就是取長軸的一半和短軸的一半。
7)、畫三角形/多邊形(drawPath)
我們想一下,如果繪製三角形/多邊形的話需要哪些要素,能確定多邊形的形狀最重要的因素就是角,那麼這些角就是一個座標
Path path = new Path();
path.moveTo(80, 200);// 此點為多邊形的起點
path.lineTo(120, 250);
path.lineTo(80, 250);
path.close(); // 使這些點構成封閉的多邊形
canvas.drawPath(path, p);
這裡需要介紹一下Path物件了,這個物件見名知意,是路徑的意思,它有兩個引數:
引數一:x座標
引數二:y座標
路徑是多個點相連線的。所以Path提供了兩個方法:moveTo和lineTo
moveTo方法的作用是設定我們繪製路徑的開始點,如果沒有這個方法的呼叫的話,系統預設的開始點是(0,0)點
lineTo方法就是將路徑的上一個座標點和當前座標點進行連線,或者可以認為設定多邊形的每個角的座標點
那麼對於三角形的話,我們需要三個點即可。
這個畫三角形其實我們用上面的畫直線的方法也可以實現的,反過來也是,我們用Path物件也是可以畫出一條直線的,那麼他們的本質區別是:
繪製路徑方式的焦點是角(座標點)
繪製直線的方式的焦點是邊(長度)
8)、畫點(drawPoint)
canvas.drawPoint(60, 390, p);//畫一個點
canvas.drawPoints(new float[]{60,400,65,400,70,400}, p);//畫多個點
這裡有兩個方法:
drawPoint
引數一:點的x座標
引數二:點的y座標
引數三:畫筆物件
drawPoints
引數一:多個點的陣列
引數二:畫筆物件
9)、畫貝塞爾曲線(drawPath)
這種曲線其實我們在開發過程中很少用到,不過在圖形學中繪製貝塞爾曲線的時候,我們需要的要素是:起始點+控制點+終點
Path path2=new Path();
path2.moveTo(100, 320);//設定Path的起點
path2.quadTo(150, 310, 170, 400); //設定貝塞爾曲線的控制點座標和終點座標
canvas.drawPath(path2, p);//畫出貝塞爾曲線
它也是使用Path物件的。不過用的是quadTo方法
引數一:控制點的x座標
引數二:控制點的y座標
引數三:終點的x座標
引數四:終點的y座標
這裡需要注意的是,呼叫moveTo方法來確定開始座標的,如果沒有呼叫這個方法,那麼起始點座標預設是:(0,0)
10)、繪製圖片(drawBitmap)
//畫圖片,就是貼圖
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
canvas.drawBitmap(bitmap, 250,360, p);
引數一:圖片物件Bitmap
引數二:圖片相對於裝置螢幕的left值
引數二:圖片相對於裝置螢幕的top值
其實我們可以把圖片認為是一個矩形,因為圖片本身是有長度和寬度的,所以這裡只需要矩形的左上角的座標點,就可以確定這張圖片在螢幕中的位置了。
上面就介紹完了Path物件和Canvas物件,他們兩個物件是我們自定義檢視的基礎,所以這部分內容一定要掌握,當然這兩個物件沒什麼難度的,只要對幾何圖形有點了解的同學,這些東東是很簡單的。
二、顏色渲染器Shader物件
下面再來看下一個知識點:顏色渲染Shader物件
為什麼我要把Shader物件單獨拿出來說一下呢?因為這個物件在對於我們處理圖形特效的時候是非常有用的
下面來看一下Android中Shader物件
在Android Api中關於顏色渲染的幾個重要的類:
Shader,BitmapShader,ComposeShader,LinearGradient,RadialGradient,SweepGradient
它們之間的關係是:
Shader是後面幾個類的父類
該類作為基類主要是返回繪製時顏色的橫向跨度。其子類可以作用與Piant。通過 paint.setShader(Shader shader);來實現一些渲染效果。之作用與圖形不作用與bitmap。
構造方法為預設的構造方法。
列舉:
emun Shader.TileMode
定義了平鋪的3種模式:
static final Shader.TileMode CLAMP: 邊緣拉伸.
static final Shader.TileMode MIRROR:在水平方向和垂直方向交替景象, 兩個相鄰影象間沒有縫隙.
Static final Shader.TillMode REPETA:在水平方向和垂直方向重複擺放,兩個相鄰影象間有縫隙縫隙.
方法:
1. boolean getLoaclMatrix(Matrix localM); 如果shader有一個非本地的矩陣將返回true.
localM:如果不為null將被設定為shader的本地矩陣.
2. void setLocalMatrix(Matrix localM);
設定shader的本地矩陣,如果localM為空將重置shader的本地矩陣。
Shader的直接子類:
BitmapShader : 點陣圖影象渲染
LinearGradient : 線性渲染
RadialGradient : 環形渲染
SweepGradient : 掃描漸變渲染/梯度渲染
ComposeShader : 組合渲染,可以和其他幾個子類組合起來使用
是不是很像Animation及其子類的關係(AlphaAnimation,RotateAnimation,ScaleAnimation,TranslateAnimation, AnimationSet)
既有具體的渲染效果,也有渲染效果的組合
下面說下Shader的使用步驟:
1. 構建Shader物件
2. 通過Paint的setShader方法設定渲染物件
3.設定渲染物件
4.繪製時使用這個Paint物件
那麼下面就開始來介紹各個Shader的相關知識:
1、BitmapShader
public BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)
呼叫這個方法來產生一個畫有一個位圖的渲染器(Shader)。
bitmap 在渲染器內使用的點陣圖
tileX The tiling mode for x to draw the bitmap in. 在點陣圖上X方向渲染器平鋪模式
tileY The tiling mode for y to draw the bitmap in. 在點陣圖上Y方向渲染器平鋪模式
TileMode:
CLAMP :如果渲染器超出原始邊界範圍,會複製範圍內邊緣染色。
REPEAT :橫向和縱向的重複渲染器圖片,平鋪。
MIRROR :橫向和縱向的重複渲染器圖片,這個和REPEAT重複方式不一樣,他是以映象方式平鋪。
程式碼:
package com.tony.shader;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;
public class BitmapShaderView extends View {
private BitmapShader bitmapShader = null;
private Bitmap bitmap = null;
private Paint paint = null;
private ShapeDrawable shapeDrawable = null;
private int BitmapWidth = 0;
private int BitmapHeight = 0;
public BitmapShaderView(Context context) {
super(context);
// 得到影象
bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.cat))
.getBitmap();
BitmapWidth = bitmap.getWidth();
BitmapHeight = bitmap.getHeight();
// 構造渲染器BitmapShader
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR,Shader.TileMode.REPEAT);
}
public BitmapShaderView(Context context,AttributeSet set) {
super(context, set);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//將圖片裁剪為橢圓形
//構建ShapeDrawable物件並定義形狀為橢圓
shapeDrawable = new ShapeDrawable(new OvalShape());
//得到畫筆並設定渲染器
shapeDrawable.getPaint().setShader(bitmapShader);
//設定顯示區域
shapeDrawable.setBounds(20, 20,BitmapWidth-140,BitmapHeight);
//繪製shapeDrawable
shapeDrawable.draw(canvas);
}
}
效果圖:
2、LinearGradient
相信很多人都看過歌詞同步的效果, 一是豎直方向的滾動,另一方面是水平方面的歌詞顏色漸變點亮效果,這種效果怎麼做呢? 這就需要用到LinearGradient線性渲染,下面還是先看具體的使用:
LinearGradient有兩個建構函式;
public LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)
引數:
float x0: 漸變起始點x座標
float y0:漸變起始點y座標
float x1:漸變結束點x座標
float y1:漸變結束點y座標
int[] colors:顏色 的int 陣列
float[] positions: 相對位置的顏色陣列,可為null, 若為null,可為null,顏色沿漸變線均勻分佈
Shader.TileMode tile: 渲染器平鋪模式
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,Shader.TileMode tile)
float x0: 漸變起始點x座標
float y0:漸變起始點y座標
float x1:漸變結束點x座標
float y1:漸變結束點y座標
int color0: 起始漸變色
int color1: 結束漸變色
Shader.TileMode tile: 渲染器平鋪模式
程式碼:
package com.tony.shader;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.graphics.Shader;
import android.view.View;
public class LinearGradientView extends View {
private LinearGradient linearGradient = null;
private Paint paint = null;
public LinearGradientView(Context context)
{
super(context);
linearGradient = new LinearGradient(0, 0, 100, 100, new int[] {
Color.YELLOW, Color.GREEN, Color.TRANSPARENT, Color.WHITE }, null,
Shader.TileMode.REPEAT);
paint = new Paint();
}
public LinearGradientView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//設定渲染器
paint.setShader(linearGradient);
//繪製圓環
canvas.drawCircle(240, 360, 200, paint);
}
}
效果:
關於這個渲染物件,我們需要多解釋一下了,因為這個渲染器用的地方很多:
我們在具體看一下他的構造方法中的引數含義:
Paint paint2 = new Paint();
paint2.setColor(Color.BLACK);
paint2.setStrokeWidth(5);
paint2.setStyle(Paint.Style.FILL);
Shader mShader = new LinearGradient(0,0,100,100,
Color.RED,
Color.BLUE, Shader.TileMode.CLAMP);
paint2.setShader(mShader);
Rect rect = new Rect();
rect.left = 0;
rect.right = 300;
rect.top = 0;
rect.bottom = 300;
canvas.drawRect(rect, paint2);
效果圖:
我們把構造方法中的值改變一下:
Shader mShader = new LinearGradient(0,0,300,300,
Color.RED,
Color.BLUE, Shader.TileMode.CLAMP);
在看一下效果:
這裡我們就是到了構造方法中的四個引數值的含義了:
引數一:渲染開始點的x座標
引數二:渲染開始點的y座標
引數三:渲染結束點的x座標
引數四:渲染結束點的y座標
因為這裡我們設定矩形的大小是高和寬都是300
所以,從第一個例子中我們可以看出:渲染結束點之後的顏色是最後一種顏色:藍色
我們在將程式碼改變一下:
Shader mShader = new LinearGradient(0,0,300,0,
Color.RED,
Color.BLUE, Shader.TileMode.CLAMP);
效果:
結束點的座標設定成:(300,0)就實現了橫向渲染
當然我們也可以實現縱向渲染的,這裡就不演示了。
在修改一下程式碼:
Shader mShader = new LinearGradient(0,0,100,100,
Color.RED,
Color.BLUE, Shader.TileMode.MIRROR);
效果:
我們將渲染模式改成:Shader.TileMode.MIRROR 映象模式了
我們看到效果,當渲染結束點是(100,100)的時候,那麼後面還是會繼續渲染的,而且是相反的(就像照鏡子一樣),然後在渲染一下,每次渲染的效果都是和之前的相反。因為矩形的長度和寬度都是300,所以這裡會渲染三次。
我們在將程式碼修改一下:
Shader mShader = new LinearGradient(0,0,100,100,
Color.RED,
Color.BLUE, Shader.TileMode.REPEAT);
將渲染模式改成:Shader.TileMode.REPEAT 重複模式了
效果:
這裡看到也是會渲染三次的,但是和映象模式不同的是,它們的渲染方向都是一致的。
從上面的三種渲染模式可以看出來,之後渲染的結束點小於渲染圖形的大小的時候才會有效果的,如果我們把大小改一下:
Shader mShader = new LinearGradient(0,0,300,300,
Color.RED,
Color.BLUE, Shader.TileMode.REPEAT);
我們渲染結束點改成矩形的高度和寬度大小效果:
效果和Shader.TileMode.CLAMP一樣的。
這種渲染器用的地方還是很多的,我們後面介紹長條漸變的SeekBar就要用到這種渲染器
3、RadialGradient
圓形渲染器,這種渲染器很好理解,就是同心圓的渲染機制
public RadialGradient(float x, float y, float radius, int[] colors, float[] positions,Shader.TileMode tile)
float x: 圓心X