Android提供了Shader类专门用来渲染图像以及一些几何图形,Shader下面包括几个直接子类,分别是BitmapShader、 ComposeShader、LinearGradient、RadialGradient、SweepGradient。BitmapShader主要用来渲染图像,LinearGradient用来进行线性渲染,RadialGradient用来进行环形渲染,SweepGradient用来进行梯度演染,BitmapShader则是一个棍合渲染,可以和其他几个了类组合起来使用。下面的示例将分别分析它们的使用方法。
如果需要将一张图片裁剪成椭圆或圆形等形状展示给用户,这时需要使用BitmapShader类来裁剪,我们随时可以看到一些渐变的效果,而在 Android中可以用LinearGradient、RadialGradient、SweepGradient很轻松地来完成。首先来看看示例的运行效果,如图5-16所示,每个图形分别使用了不同的渲染。
Shader类的使用,都需要先构建Shader对象,然后通过Paint的setShader方法来设置渲染对象,然后在绘制时使用这个Paint对象即可。当然,用不同的渲染时需要构建不同的对象,具体实现的代码如下:
001 | package com.yarin.android.Examples_05_11; |
002 | |
003 | import android.content.Context; |
004 | import android.graphics.Bitmap; |
005 | import android.graphics.BitmapShader; |
006 | import android.graphics.Canvas; |
007 | import android.graphics.Color; |
008 | import android.graphics.ComposeShader; |
009 | import android.graphics.LinearGradient; |
010 | import android.graphics.Paint; |
011 | import android.graphics.PorterDuff; |
012 | import android.graphics.RadialGradient; |
013 | import android.graphics.Shader; |
014 | import android.graphics.SweepGradient; |
015 | import android.graphics.drawable.BitmapDrawable; |
016 | import android.graphics.drawable.ShapeDrawable; |
017 | import android.graphics.drawable.shapes.OvalShape; |
018 | import android.view.KeyEvent; |
019 | import android.view.MotionEvent; |
020 | import android.view.View; |
021 | |
022 | public class GameView extends View implements Runnable |
023 | { |
024 | /** 声明Bitmap对象 */ |
025 | Bitmap mBitQQ = null ; |
026 | int BitQQwidth = 0 ; |
027 | int BitQQheight = 0 ; |
028 | |
029 | Paint mPaint = null ; |
030 | |
031 | /** Bitmap渲染 */ |
032 | Shader mBitmapShader = null ; |
033 | |
034 | /** 线性渐变渲染 */ |
035 | Shader mLinearGradient = null ; |
036 | |
037 | /** 混合渲染 */ |
038 | Shader mComposeShader = null ; |
039 | |
040 | /** 唤醒渐变渲染 */ |
041 | Shader mRadialGradient = null ; |
042 | |
043 | /** 梯度渲染 */ |
044 | Shader mSweepGradient = null ; |
045 | |
046 | |
047 | ShapeDrawable mShapeDrawableQQ = null ; |
048 | |
049 | public GameView(Context context) |
050 | { |
051 | super (context); |
052 | |
053 | /** 装载资源 */ |
054 | mBitQQ = ((BitmapDrawable) getResources().getDrawable(R.drawable.qq)).getBitmap(); |
055 | |
056 | /** 得到图片的宽度和高度 */ |
057 | BitQQwidth = mBitQQ.getWidth(); |
058 | BitQQheight = mBitQQ.getHeight(); |
059 | |
060 | /** 创建BitmapShader对象 */ |
061 | mBitmapShader = new BitmapShader(mBitQQ,Shader.TileMode.REPEAT,Shader.TileMode.MIRROR); |
062 | |
063 | /** 创建LinearGradient并设置渐变的颜色数组 */ |
064 | mLinearGradient = new LinearGradient( 0 , 0 , 100 , 100 , |
065 | new int []{Color.RED,Color.GREEN,Color.BLUE,Color.WHITE}, |
066 | null ,Shader.TileMode.REPEAT); |
067 | /** 这里笔者理解为“混合渲染”--大家可以有自己的理解,能明白这个意思就好*/ |
068 | mComposeShader = new ComposeShader(mBitmapShader,mLinearGradient,PorterDuff.Mode.DARKEN); |
069 | |
070 | /** 构建RadialGradient对象,设置半径的属性 */ |
071 | //这里使用了BitmapShader和LinearGradient进行混合 |
072 | //当然也可以使用其他的组合 |
073 | //混合渲染的模式很多,可以根据自己需要来选择 |
074 | mRadialGradient = new RadialGradient( 50 , 200 , 50 , |
075 | new int []{Color.GREEN,Color.RED,Color.BLUE,Color.WHITE}, |
076 | null ,Shader.TileMode.REPEAT); |
077 | /** 构建SweepGradient对象 */ |
078 | mSweepGradient = new SweepGradient( 30 , 30 , new int []{Color.GREEN,Color.RED,Color.BLUE,Color.WHITE}, null ); |
079 | |
080 | mPaint = new Paint(); |
081 | |
082 | /** 开启线程 */ |
083 | new Thread( this ).start(); |
084 | } |
085 | |
086 | public void onDraw(Canvas canvas) |
087 | { |
088 | super .onDraw(canvas); |
089 | |
090 | //将图片裁剪为椭圆形 |
091 | /** 构建ShapeDrawable对象并定义形状为椭圆 */ |
092 | mShapeDrawableQQ = new ShapeDrawable( new OvalShape()); |
093 | |
094 | /** 设置要绘制的椭圆形的东西为ShapeDrawable图片 */ |
095 | mShapeDrawableQQ.getPaint().setShader(mBitmapShader); |
096 | |
097 | /** 设置显示区域 */ |
098 | mShapeDrawableQQ.setBounds( 0 , 0 , BitQQwidth, BitQQheight); |
099 | |
100 | /** 绘制ShapeDrawableQQ */ |
101 | mShapeDrawableQQ.draw(canvas); |
102 | |
103 | //绘制渐变的矩形 |
104 | mPaint.setShader(mLinearGradient); |
105 | canvas.drawRect(BitQQwidth, 0 , 320 , 156 , mPaint); |
106 | |
107 | //显示混合渲染效果 |
108 | mPaint.setShader(mComposeShader); |
109 | canvas.drawRect( 0 , 300 , BitQQwidth, 300 +BitQQheight, mPaint); |
110 | |
111 | //绘制环形渐变 |
112 | mPaint.setShader(mRadialGradient); |
113 | canvas.drawCircle( 50 , 200 , 50 , mPaint); |
114 | |
115 | //绘制梯度渐变 |
116 | mPaint.setShader(mSweepGradient); |
117 | canvas.drawRect( 150 , 160 , 300 , 300 , mPaint); |
118 | |
119 | } |
120 | |
121 | // 触笔事件 |
122 | public boolean onTouchEvent(MotionEvent event) |
123 | { |
124 | return true ; |
125 | } |
126 | |
127 | |
128 | // 按键按下事件 |
129 | public boolean onKeyDown( int keyCode, KeyEvent event) |
130 | { |
131 | return true ; |
132 | } |
133 | |
134 | |
135 | // 按键弹起事件 |
136 | public boolean onKeyUp( int keyCode, KeyEvent event) |
137 | { |
138 | return false ; |
139 | } |
140 | |
141 | |
142 | public boolean onKeyMultiple( int keyCode, int repeatCount, KeyEvent event) |
143 | { |
144 | return true ; |
145 | } |
146 | |
147 | |
148 | /** |
149 | * 线程处理 |
150 | */ |
151 | public void run() |
152 | { |
153 | while (!Thread.currentThread().isInterrupted()) |
154 | { |
155 | try |
156 | { |
157 | Thread.sleep( 100 ); |
158 | } |
159 | catch (InterruptedException e) |
160 | { |
161 | Thread.currentThread().interrupt(); |
162 | } |
163 | //使用postInvalidate可以直接在线程中更新界面 |
164 | postInvalidate(); |
165 | } |
166 | } |
167 | } |
至此,Android的Shader用法也介绍完了,谢谢阅读