Android 繪圖學(xué)習(xí)
1 linearGradient簡(jiǎn)介
linearGradient線性漸變献酗,會(huì)用到Paint的setShader蚜厉,Shader 被稱為著色器,在opengl中這個(gè)概念經(jīng)常被用到,android中的shader主要用來(lái)給圖像著色惋耙,Shader在繪制過(guò)程中會(huì)返回橫向重要的顏色組乱陡,Paint設(shè)置shader后浇揩,繪制時(shí)會(huì)從shader中獲取顏色,也就是需要shader告訴畫筆某處的顏色值憨颠。
Shader 具體實(shí)現(xiàn)類包括:
BitmapShader,ComposeShader,LinearGradient,RadialGradient,SweepGradient
https://blog.csdn.net/u010126792/article/details/83787779 我在 這篇文章中寫過(guò)android漸變的實(shí)現(xiàn)胳徽,此處就從LinearGradient開(kāi)始學(xué)習(xí)。
LinearGradient兩種構(gòu)造函數(shù):
/**
* Create a shader that draws a linear gradient along a line.
*
* @param x0 The x-coordinate for the start of the gradient line
* @param y0 The y-coordinate for the start of the gradient line
* @param x1 The x-coordinate for the end of the gradient line
* @param y1 The y-coordinate for the end of the gradient line
* @param color0 The color at the start of the gradient line.
* @param color1 The color at the end of the gradient line.
* @param tile The Shader tiling mode
*/
public LinearGradient(float x0, float y0, float x1, float y1,
@ColorInt int color0, @ColorInt int color1, @NonNull TileMode tile) 爽彤;
/**
* Create a shader that draws a linear gradient along a line.
*
* @param x0 The x-coordinate for the start of the gradient line
* @param y0 The y-coordinate for the start of the gradient line
* @param x1 The x-coordinate for the end of the gradient line
* @param y1 The y-coordinate for the end of the gradient line
* @param colors The colors to be distributed along the gradient line
* @param positions May be null. The relative positions [0..1] of
* each corresponding color in the colors array. If this is null,
* the the colors are distributed evenly along the gradient line.
* @param tile The Shader tiling mode
*/
public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[], @Nullable float positions[], @NonNull TileMode tile) 养盗;
參數(shù)說(shuō)明:
(x0,y0):漸變起始點(diǎn)坐標(biāo)
(x1,y1):漸變結(jié)束點(diǎn)坐標(biāo)
color0:漸變開(kāi)始點(diǎn)顏色,16進(jìn)制的顏色表示,必須要帶有透明度
color1:漸變結(jié)束顏色
colors:漸變數(shù)組
positions:位置數(shù)組适篙,position的取值范圍[0,1],作用是指定某個(gè)位置的顏色值往核,如果傳null,漸變就線性變化嚷节。
tile:用于指定控件區(qū)域大于指定的漸變區(qū)域時(shí)聂儒,空白區(qū)域的顏色填充方法虎锚。
- CLAMP邊緣拉伸,為被shader覆蓋區(qū)域衩婚,使用shader邊界顏色進(jìn)行填充
-REPEAT 在水平和垂直兩個(gè)方向上重復(fù)窜护,相鄰圖像沒(méi)有間隙
-MIRROR以鏡像的方式在水平和垂直兩個(gè)方向上重復(fù),相鄰圖像有間隙
第一個(gè)構(gòu)造函數(shù)可以指定兩個(gè)顏色之間的漸變非春,第二個(gè)構(gòu)造函數(shù)可以指定多個(gè)顏色之間的漸變柄慰,線性漸變不但可以代碼實(shí)現(xiàn)還可以xml文件實(shí)現(xiàn),這里只講解代碼實(shí)現(xiàn)方式税娜。
2 兩種顏色的線性漸變
只需要設(shè)置開(kāi)始結(jié)束點(diǎn)坐標(biāo)坐搔,開(kāi)始顏色,結(jié)束顏色敬矩。
實(shí)例代碼:
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(3);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(20);
LinearGradient linearGradient = new LinearGradient(getWidth(),400,0,0,Color.RED,Color.GREEN, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
canvas.drawRect(0,0,getWidth(),400,mPaint);
xml中設(shè)置漸變可以通過(guò)設(shè)置angle角度來(lái)改變漸變的開(kāi)始結(jié)束概行,可以設(shè)置從上到下,從下到上弧岳,從左到右凳忙,從右到左,代碼中如何設(shè)置呢禽炬?
3 如何通過(guò)坐標(biāo)設(shè)置漸變方向:
通過(guò)坐標(biāo)可以輕松實(shí)現(xiàn)涧卵,漸變方向的控制:
(0,0)->(0,400)從上到下
(0,400)->(0,0) 從下到上
0,0)->(getMeasuredWidth(),0) 表示從左到右
(getMeasuredWidth(),0)->(0,0) 表示從右到左
0,0)-> (getMeasuredWidth(),getMeasuredHeight()) 斜角,從左上角到右下角
從左到右:
從右到左:
** 漸變填充顏色總結(jié)**
要實(shí)現(xiàn)從上到下需要設(shè)置shader開(kāi)始結(jié)束點(diǎn)坐標(biāo)為左上角到左下角或右上角到右下角坐標(biāo)腹尖。
要實(shí)現(xiàn)從下到上需要設(shè)置shader開(kāi)始結(jié)束點(diǎn)坐標(biāo)為左下角到左上角或右下角到右上角柳恐。
要實(shí)現(xiàn)從左到右需要設(shè)置shader開(kāi)始結(jié)束點(diǎn)坐標(biāo)為左上角到右上角或者左下角到右下角。
要實(shí)現(xiàn)從右到左需要設(shè)置shader開(kāi)始結(jié)束坐標(biāo)為右上角到左上角或者右下角到左下角热幔。
要實(shí)現(xiàn)對(duì)角shader乐设,需要設(shè)置開(kāi)始結(jié)束點(diǎn)坐標(biāo)左上角到右下角。
4 多顏色填充 colors绎巨,positions數(shù)組參數(shù)講解
LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[], @Nullable float positions[], @NonNull TileMode tile) 近尚;
positions為null時(shí),線性填充场勤,和沒(méi)有positions數(shù)組的構(gòu)造函數(shù)效果一樣戈锻。
Positions數(shù)組中值為0-1,0表示開(kāi)始繪制點(diǎn),1表示結(jié)束點(diǎn)和媳,0.5對(duì)應(yīng)中間點(diǎn)等等格遭。數(shù)組中位置信息對(duì)應(yīng)顏色數(shù)組中的顏色。
//例如
int [] colors = {Color.RED,Color.GREEN, Color.BLUE};
float[] position = {0f, 0.3f, 1.0f};
上面position[0]對(duì)應(yīng)數(shù)組中的第一個(gè)RED窗价,0.3f的位置對(duì)應(yīng)顏色中的GREEN如庭,1.0f的位置對(duì)應(yīng)顏色中的BLUE,所以從0-0.3的位置是從RED到GREEN的漸變,從0.3到1.0的位置的顏色漸變是GREEN到BLUE坪它。
int [] colors = {Color.RED,Color.GREEN, Color.BLUE};
float[] position = {0f, 0.3f, 1.0f};
LinearGradient linearGradient = new LinearGradient(0,0,getMeasuredWidth(),0,colors,position, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
如果把0.3改成0.7骤竹,
5 利用LinearGradient實(shí)現(xiàn)變色字體
利用設(shè)置了變色shader的畫筆,就可以畫出變色字體:
int [] colors = {Color.RED,Color.GREEN, Color.BLUE};
float[] position = {0f, 0.7f, 1.0f};
LinearGradient linearGradient = new LinearGradient(0,0,getMeasuredWidth(),0,colors,position, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
// canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
canvas.drawText("Android繪圖小糊涂",0,getMeasuredHeight()/2,mPaint);
如何讓字體顏色不停地變動(dòng):
Shader 可以設(shè)置matrix變換往毡,利用translate不停地移動(dòng)shader,實(shí)現(xiàn)漸變效果蒙揣,下面的實(shí)例不能用于生產(chǎn)環(huán)境,我只是寫個(gè)例子开瞭,后面會(huì)開(kāi)文章講解可用于生產(chǎn)的漸變懒震。
int [] colors = {Color.BLACK,Color.RED, Color.BLUE,Color.BLACK};
Rect rect = new Rect();
mPaint.getTextBounds(str,0,str.length(), rect);
int fontWidth = rect.width();
linearGradient = new LinearGradient(0,0,-fontWidth+10,0,colors,null, Shader.TileMode.CLAMP);
Matrix matrix = new Matrix();
matrix.setTranslate(tran,0);
linearGradient.setLocalMatrix(matrix);
tran = (tran + advance) ;
if (tran >= fontWidth*2){
tran = 0;
}
mPaint.setShader(linearGradient);
canvas.drawText(str,0,getMeasuredHeight()/2,mPaint);
invalidate();
TileMode 邊緣填充模式
如果shader的大小小于view的大小時(shí)如何繪制其他沒(méi)有被shader覆蓋的區(qū)域?
跟最后一個(gè)參數(shù)有關(guān)嗤详,
-CLAMP
邊緣拉伸个扰,利用邊緣的顏色,填充剩余部分
-REPEAT
在水平和垂直兩個(gè)方向上重復(fù)葱色,相鄰圖像沒(méi)有間隙递宅,重復(fù)shader
-MIRROR
以鏡像的方式在水平和垂直兩個(gè)方向上重復(fù),相鄰圖像有間隙苍狰,鏡面shader
LinearGradient linearGradient = new LinearGradient(0,0,getMeasuredWidth()/2,getMeasuredHeight()/2,Color.RED,Color.GREEN, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
CLAMP:
REPEAT:
MIRROR:
如果想要從對(duì)角線設(shè)置shader办龄,圖形最好是正方形這樣比較好看設(shè)置:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width,width);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
LinearGradient linearGradient = new LinearGradient(0,0,getMeasuredWidth()/2,getMeasuredHeight()/2,Color.RED,Color.GREEN, Shader.TileMode.MIRROR);
mPaint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
}
android繪圖之Paint(1)
android繪圖之Canvas基礎(chǔ)(2)
Android繪圖之Path(3)
Android繪圖之drawText繪制文本相關(guān)(4)
Android繪圖之Canvas概念理解(5)
Android繪圖之Canvas變換(6)
Android繪圖之Canvas狀態(tài)保存和恢復(fù)(7)
Android繪圖之PathEffect (8)
Android繪圖之LinearGradient線性漸變(9)
Android繪圖之SweepGradient(10)
Android繪圖之RadialGradient 放射漸變(11)
Android繪制之BitmapShader(12)
Android繪圖之ComposeShader,PorterDuff.mode及Xfermode(13)
Android繪圖之drawText,getTextBounds,measureText,FontMetrics,基線(14)
Android繪圖之貝塞爾曲線簡(jiǎn)介(15)
Android繪圖之PathMeasure(16)
Android 動(dòng)態(tài)修改漸變 GradientDrawable