尊重原創,轉載請标明出處 http://blog.csdn.net/abcdef314159
上一篇講到paint的一些常用方法,其中遺留了一些,這篇先講解其中的一個Shader渲染,我們知道Shader渲染Android提供了5個子類,有BitmapShader,ComposeShader,LinearGradient,RadialGradient,SweepGradient。Shader中有一個TileMode,共有3種模式,
CLAMP:當圖檔小于繪制尺寸時要進行邊界拉伸來填充
REPEAT:當圖檔小于繪制尺寸時重複平鋪
MIRROR:當圖檔小于繪制尺寸時鏡像平鋪
我們先來看一下BitmapShader,
public class ShaderView extends View {
private Bitmap mBitmap;
private Shader mBitmapShader = null;
private Paint mPaint;
public ShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
Shader.TileMode.MIRROR);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mBitmapShader);
canvas.drawRect(0, 0, mBitmap.getWidth() * 4, mBitmap.getHeight() * 4,
mPaint);
}
}
運作結果為
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TMxMjMxYDM1EzMyYDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
我們看到左右平鋪,上下鏡像,在來改一下,隻需要把上面的mBitmapShader改一下就可
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP,
Shader.TileMode.MIRROR);
看到上下鏡像,左右拉伸,再來看一下LinearGradient
public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
TileMode tile)
float x0 :漸變的x坐标起點
float y0 :漸變的y坐标起點
float x1 :漸變的x坐标終點
float y1 :漸變的y坐标終點
int colors[]:漸變的顔色數組
float positions[]:顔色的相對位置
TileMode tile:上面的3種模式
public class ShaderView extends View {
private Shader mLinearGradient = null;
private Paint mPaint;
public ShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinearGradient = new LinearGradient(0, 0, 100, 100, new int[] {
Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE },
new float[] { 0, .1F, .8F, .9F }, Shader.TileMode.REPEAT);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mLinearGradient);
canvas.drawRect(0, 0, 900, 1000, mPaint);
}
}
我們看到上面的小數數組是漸變的相對位置,如果positions為空,這均勻分布,修改一下
mLinearGradient = new LinearGradient(0, 0, 100, 100, new int[] {
Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE }, null,
Shader.TileMode.REPEAT);
再來修改一下模式,因為最後一個是白色容易和手機螢幕混淆,是以添加了一個綠色
mLinearGradient = new LinearGradient(0, 0, 100, 100,
new int[] { Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE,
Color.GREEN }, null, Shader.TileMode.CLAMP);
我們看到最後一個顔色是拉伸,再修改一下
mLinearGradient = new LinearGradient(0, 0, 100, 100,
new int[] { Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE,
Color.GREEN }, null, Shader.TileMode.MIRROR);
鏡像模式,是以感覺有點對稱。在看一下LinearGradient的另一個構造方法,
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
TileMode tile)
其中color0是顔色的起始點,color1是顔色的終止點,我們就示範一個看看
mLinearGradient = new LinearGradient(0, 0, 100, 100, Color.RED,
Color.YELLOW, Shader.TileMode.MIRROR);
再來看一下RadialGradient
RadialGradient(float x, float y, float radius,
int colors[], float positions[], TileMode tile)
它實作的是環形漸變,
x:漸變的中心x坐标
y:漸變的中心y坐标
radius:漸變的半徑
colors:梯度漸變的顔色數組
positions:和LinearGradient類似,用來指定顔色數組的相對位置
public class ShaderView extends View {
private Shader mRadialGradient = null;
private Paint mPaint;
public ShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRadialGradient = new RadialGradient(200, 400, 100, new int[] {
Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN }, null,
Shader.TileMode.REPEAT);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mRadialGradient);
canvas.drawRect(0, 0, 900, 1000, mPaint);
}
}
運作結果如上,再來修改一下
mRadialGradient = new RadialGradient(200, 400, 100, new int[] {
Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN }, null,
Shader.TileMode.CLAMP);
再來修改一下
mRadialGradient = new RadialGradient(200, 400, 100, new int[] {
Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN }, null,
Shader.TileMode.MIRROR);
還有個構造方法,這裡就不在示範
RadialGradient(float x, float y, float radius,
int color0, int color1, TileMode tile)
下面看一下SweepGradient
SweepGradient(float cx, float cy,
int colors[], float positions[])
cx,cy:掃描中心的x,y坐标
colors:漸變的數組顔色
positions:漸變的相對位置
public class ShaderView extends View {
private Shader mSweepGradient = null;
private Paint mPaint;
public ShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSweepGradient = new SweepGradient(400, 400, new int[] { Color.YELLOW,
Color.RED, Color.BLUE, Color.GREEN }, new float[] { 0, .2F,
.6F, .9F });
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mSweepGradient);
canvas.drawCircle(400, 400, 300, mPaint);
}
}
還有最後一個ComposeShader,這個是組合的Shader
public class ShaderView extends View {
private Shader mSweepGradient = null;
private Shader mBitmapShader = null;
private Shader mComposeShader = null;
private Paint mPaint;
private Bitmap mBitmap;
public ShaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
Shader.TileMode.MIRROR);
mSweepGradient = new SweepGradient(mBitmap.getWidth() * 2,
mBitmap.getWidth() * 2, new int[] { Color.YELLOW,
Color.RED, Color.BLUE, Color.GREEN }, new float[] { 0, .2F,
.6F, .9F });
mComposeShader = new ComposeShader(mBitmapShader, mSweepGradient,
PorterDuff.Mode.DARKEN);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mComposeShader);
canvas.drawRect(0, 0, mBitmap.getWidth() * 4, mBitmap.getHeight() * 4,
mPaint);
}
}
在上一篇講到Paint的時候講到PorterDuff.Mode有18種模式,這裡隻是随便使用了其中的一種。OK,Paint的setShader(Shader shader)方法到此先告一段落。