天天看點

Android Paint之Shader渲染詳解

尊重原創,轉載請标明出處    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);
	}

}
           

運作結果為

Android Paint之Shader渲染詳解

我們看到左右平鋪,上下鏡像,在來改一下,隻需要把上面的mBitmapShader改一下就可

mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP,
				Shader.TileMode.MIRROR);
           
Android Paint之Shader渲染詳解

看到上下鏡像,左右拉伸,再來看一下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);
	}
}
           
Android Paint之Shader渲染詳解

我們看到上面的小數數組是漸變的相對位置,如果positions為空,這均勻分布,修改一下

mLinearGradient = new LinearGradient(0, 0, 100, 100, new int[] {
				Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE }, null,
				Shader.TileMode.REPEAT);
           
Android Paint之Shader渲染詳解

再來修改一下模式,因為最後一個是白色容易和手機螢幕混淆,是以添加了一個綠色

mLinearGradient = new LinearGradient(0, 0, 100, 100,
				new int[] { Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE,
						Color.GREEN }, null, Shader.TileMode.CLAMP);
           
Android Paint之Shader渲染詳解

我們看到最後一個顔色是拉伸,再修改一下

mLinearGradient = new LinearGradient(0, 0, 100, 100,
				new int[] { Color.RED, Color.YELLOW, Color.BLACK, Color.WHITE,
						Color.GREEN }, null, Shader.TileMode.MIRROR);
           
Android Paint之Shader渲染詳解

鏡像模式,是以感覺有點對稱。在看一下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);
           
Android Paint之Shader渲染詳解

再來看一下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);
	}
}
           
Android Paint之Shader渲染詳解

運作結果如上,再來修改一下

mRadialGradient = new RadialGradient(200, 400, 100, new int[] {
				Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN }, null,
				Shader.TileMode.CLAMP);
           
Android Paint之Shader渲染詳解

再來修改一下

mRadialGradient = new RadialGradient(200, 400, 100, new int[] {
				Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN }, null,
				Shader.TileMode.MIRROR);
           
Android Paint之Shader渲染詳解

還有個構造方法,這裡就不在示範

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);
	}
}
           
Android Paint之Shader渲染詳解

還有最後一個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);
	}
}
           
Android Paint之Shader渲染詳解

在上一篇講到Paint的時候講到PorterDuff.Mode有18種模式,這裡隻是随便使用了其中的一種。OK,Paint的setShader(Shader shader)方法到此先告一段落。