一、在Android中访问图片
在Android中操作图片是通过使用Drawable类来完成的。Drawable类有很多个子类,如BitmapDrawable用来操作位图;ColorDrawable用来操作颜色;ShapeDrawable用来操作各种形状。
有三种方法实例化Drawable对象:一是使用保存在工程中的一个图片文件;二是使用XML定义Drawable属性;三是构造方法实例化,这种方法在实际开发中一般用不到。
1、使用图片文件创建Drawable对象
1)、在工程的资源文件夹下放入一个image1.jpg图片文件
2)、创建布局文件main.xml并在其中添加一个ImageView组件
3)、创建Activity,并实例化ImageView组件
4)、调用ImageView的setImageResource()方法,引用资源id
public class MainActivity extends Activity {
private ImageView imageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.ImageView01);
//为ImageView设置图片源
imageView.setImageResource(R.drawable.image1);
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Drawable Test" />
<ImageView
android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
2、使用XML文件定义Drawable属性
下面的代码演示了如何在AndroidManifest.xml配置文件中引用资源图标
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" />
上一个例子也可以通过这种方式来配置ImageView资源
<ImageView
android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image1" />
3、Bitmap和BitmapFactory
当文件保存在SDCard中时,通过这两个类来读取文件
下面的代码演示了如何从SDCard中读取图片文件斌将其设置为壁纸
1)、在SDCard中添加一个名称为image2.jpg的图片文件
2)、创建Activity
3)、在onCreate()方法中通过BitmapFactory的decodeFile()方法传递文件路径,获得Bitmap对象
4)、调用setWallpaper()方法设置桌面
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String path = "/sdcard/image2.jpg";
//通过BitmapFactory获得Bitmap实例
Bitmap bm = BitmapFactory.decodeFile(path);
try {
//设置桌面
setWallpaper(bm);
} catch (Exception e) {
e.printStackTrace();
}
}
}
二、Android中的动画
在Android中提供了两种动画实现方式:一种是Tween动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化;另一种是Frame动画,这是一种传统的动画方法,通过顺序播放排好的图片来实现,类似电影。
1、Tween动画
Tween动画能完成一系列简单的变化(如位置、尺寸、透明度和旋转等)。Tween动画类位于android.view.animation包中,该在包中包含了一些常用的动画实现类。
- Animation:动画抽象类,其他几个实现类继承该类
- ScaleAnimation:控制尺寸变化的动画类
- AlphaAnimation:控制透明度变化的动画类
- RotateAnimation:控制旋转变化的动画类
- TranslateAnimation:控制位置变化的动画类
- AnimationSet:定义动画属性集合类
- AnimationUtils:动画工具类
总体来讲,Android系统Tween动画提供了四种实现方式
名称 | 实现类 | 常用构造方法 | 参数说明 |
Alpha (渐变动画) | AlphaAnimation | AlphaAnimation (float fromAlpha,float toAlpha) | fromAlpha:动画开始透明度 toAlpha:动画结束透明度 (取值范围0.0~1.0) |
Scale (尺寸变化动画) | ScaleAnimation | public ScaleAnimation (float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) | fromX:起始X坐标上的伸缩尺寸 toX:结束X坐标上的伸缩尺寸 fromY:起始Y坐标上的伸缩尺寸 toY:结束Y坐标上的伸缩尺寸 pivotXType:X坐标伸缩模式(取值有 Animation.ABSOLUTE、 Animation.RELATIVE_TO_SELF、 Animation.RELATIVE_TO_PARENT) pivotXValue:相当于X坐标伸缩值 pivotYType:Y坐标伸缩模式 pivotYValue:相当于Y坐标伸缩值 |
Translate (位置变化动画) | TranslateAnimation | TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) | fromXDelta:起始X坐标 toXDelta:结束X坐标 fromYDelta:起始Y坐标 toYDelta:结束Y坐标 |
Rotate (旋转动画) | RotateAnimation | RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) | fromDegrees:旋转开始角度 toDegrees:旋转结束角度 pivotXType:X坐标伸缩模式 pivotXValue:相当于X坐标伸缩值 pivotYType:Y坐标伸缩模式 pivotYValue:相当于Y坐标伸缩值 |
Tween动画的实现方式有两种:一种是直接通过硬编码的方式在程序代码中实现;另一种是在配置文件中定义。Android系统推荐使用配置文件的方法,这种方式可扩展性较高
/**
* Tween动画
* 实现方式:硬编码
*/
public class MainActivity extends Activity {
private Button b1,b2,b3,b4;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button) findViewById(R.id.tween_Button01);
b2 = (Button) findViewById(R.id.tween_Button02);
b3 = (Button) findViewById(R.id.tween_Button03);
b4 = (Button) findViewById(R.id.tween_Button04);
imageView = (ImageView) findViewById(R.id.tween_ImageView);
//尺寸
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建Scale(尺寸)变化动画
Animation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
Animation scaleAnimation2 = new ScaleAnimation(0f, 1f, 0f, 1f,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_PARENT,0.5f);
//设置动画持续时间
scaleAnimation.setDuration(2000);
//开始动画
imageView.startAnimation(scaleAnimation);
}
});
//渐变
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation alphaAnimation = new AlphaAnimation(0.1f,0.1f);
alphaAnimation.setDuration(2000);
imageView.startAnimation(alphaAnimation);
}
});
//位置变化
b3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation translateAnimation = new TranslateAnimation(10, 100, 10, 100);
translateAnimation.setDuration(2000);
imageView.startAnimation(translateAnimation);
}
});
//旋转
b4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation rotateAnimation = new RotateAnimation(0f, +360f,
Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(2000);
imageView.startAnimation(rotateAnimation);
}
});
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/tween_ImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image1" />
<Button
android:id="@+id/tween_Button01"
android:text="Test Scale...尺寸"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/tween_Button02"
android:text="Test Alpha...透明度"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/tween_Button03"
android:text="Test Translate...位置变化"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/tween_Button04"
android:text="Test Rotate...旋转"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
下面演示如何通过配置文件实现
首先在res\anim\目录下创建各种动画的XML配置文件
my_alpha.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="5000" />
</set>
my_translate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="10"
android:toXDelta="100"
android:fromYDelta="10"
android:toYDelta="100" />
</set>
my_scale.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" />
</set>
my_rotate.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate android:fromDegrees="10"
android:toDegrees="-180"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" />
</set>
/**
* Tween动画
* 实现方式:配置文件
*/
public class MainActivity extends Activity {
private Button b1,b2,b3,b4;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button) findViewById(R.id.tween_Button01);
b2 = (Button) findViewById(R.id.tween_Button02);
b3 = (Button) findViewById(R.id.tween_Button03);
b4 = (Button) findViewById(R.id.tween_Button04);
imageView = (ImageView) findViewById(R.id.tween_ImageView);
//尺寸
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建Scale(尺寸)变化动画
Animation scaleAnimation = AnimationUtils.loadAnimation(Main3_2Activity.this, R.anim.my_scale);
//开始动画
imageView.startAnimation(scaleAnimation);
}
});
//渐变
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation alphaAnimation = AnimationUtils.loadAnimation(Main3_2Activity.this, R.anim.my_alpha);
imageView.startAnimation(alphaAnimation);
}
});
//位置变化
b3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation translateAnimation = AnimationUtils.loadAnimation(Main3_2Activity.this, R.anim.my_translate);
imageView.startAnimation(translateAnimation);
}
});
//旋转
b4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Animation rotateAnimation = AnimationUtils.loadAnimation(Main3_2Activity.this, R.anim.my_rotate);
rotateAnimation.setDuration(2000);
imageView.startAnimation(rotateAnimation);
}
});
}
}
2、Frame动画
Frame动画是顺序播放图片来产生动画效果的,类似电影。
Frame动画是通过AnimationDrawable类实现的,该类中的两个重要方法是start()和stop()分别用来开始和停止动画。动画一般通过XML配置文件来进行配置,在工程的res\anim\目录下创建一个XML配置文件,该配置文件中有一个<animation-list>根元素和若干个<item>子元素。
下面演示Frame动画的实现,该实例顺序播放4张图片。
res\anim\dance.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/d101" android:duration="500" />
<item android:drawable="@drawable/d102" android:duration="500" />
<item android:drawable="@drawable/d103" android:duration="500" />
<item android:drawable="@drawable/d104" android:duration="500" />
</animation-list>
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/d_ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@anim/dance" />
<Button
android:id="@+id/d_Button01"
android:text="Start"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/d_Button02"
android:text="Stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
public class MainActivity extends Activity {
private Button b1,b2;
private ImageView imageView;
//声明AnimationDrawable
private AnimationDrawable danceAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b1 = (Button) findViewById(R.id.d_Button01);
b2 = (Button) findViewById(R.id.d_Button02);
imageView = (ImageView) findViewById(R.id.d_ImageView01);
//获取背景色,并转换为AnimationDrawable对象
danceAnimation = (AnimationDrawable) imageView.getBackground();
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
//开始动画
danceAnimation.start();
}
});
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
danceAnimation.stop();
}
});
}
}
三、动态图形绘制
1、动态图形绘制的基本思路
创建一个类继承View类(或者继承SurfaceView类)。覆盖onDraw()方法,使用Canvas对象在界面上绘制不同的图形,使用invalidate()方法刷新界面。
下面通过一个弹球实例来讲述动态图形绘制的基本思路,该实例是在界面上动态绘制一个小球,当小球触顶时自动改变方向继续运行。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView v = new MyView(this, null);
setContentView(v);
}
//自定义视图类
class MyView extends View implements Runnable{
//图形当前坐标
private int x = 20,y = 20;
//构造方法
public MyView(Context context,AttributeSet attrs) {
super(context, attrs);
//获得焦点
setFocusable(true);
//启动线程
new Thread(this).start();
}
@Override
public void run() {
Looper.prepare();
RefreshHandler mRedrawHandler = new RefreshHandler();
while(!Thread.currentThread().isInterrupted()){
//通过发送消息更新界面
Message m = new Message();
m.what = 0x101;
mRedrawHandler.sendMessage(m);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//实例化画笔
Paint p = new Paint();
//设置画笔颜色
p.setColor(Color.GREEN);
//画圆
canvas.drawCircle(x, y, 10, p);
}
//更新界面处理器
class RefreshHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if(msg.what == 0x101){
MyView.this.update();
MyView.this.invalidate();
}
super.handleMessage(msg);
}
}
//更新坐标
private void update(){
int h = getHeight();
y += 5;
if(y >= h)
y = 20;
}
}
}
2、动态图形绘制类简介
1)、Canvas
画布,位于android.graphics包中,提供了一些画各种图形的方法,例如矩形、圆、椭圆等
方法名称 | 方法描述 |
drawText(String text, float x, float y, Paint paint) | 在屏幕上写字 |
drawPoint(float x, float y, Paint paint) | 画点 |
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) | 画线 |
drawCircle(float cx, float cy, float radius, Paint paint) | 画圆 |
drawOval(RectF oval, Paint paint) | 画椭圆 |
drawRect(RectF rect, Paint paint) | 画矩形 |
drawRoundRect(RectF rect, float rx, float ry, Paint paint) | 画圆角矩形 |
clipRect(float left, float top, float right, float bottom) | 剪辑矩形 |
clipRegion(Region region) | 剪辑区域 |
2)、Paint
涂料,用来描述图形颜色和风格,如线宽、颜色、字体等信息。位于android.graphics包中
方法名称 | 方法描述 |
Paint() | 构造方法,使用默认设置 |
setColor(int color) | 设置颜色 |
setStrokeWidth(float width) | 设置线宽 |
setTextAlign(Align align) | 设置文字对齐 |
setTextSize(float textSize) | 设置文字尺寸 |
setShader(Shader shader) | 设置渐变 |
setAlpha(int a) | 设置alpha值 |
reset() | 复位Paint默认设置 |
3)、Color
此类定义了一些颜色常量和一些创建颜色的方法。颜色的定义一般使用RGB三原色来定义。Color位于android.graphics包中。
方法或者属性名称 | 方法描述 |
BLACK | 黑色 |
BLUE | 蓝色 |
CYAN | 青色 |
DKGRAY | 深灰色 |
GRAY | 灰色 |
GREEN | 绿色 |
LTGRAY | 浅灰色 |
MAGENTA | 紫色 |
RED | 红色 |
TRANSPARENT | 透明 |
WHITE | 白色 |
YELLOW | 黄色 |
4)、Path
当我们想要画一个圆的时候,我们只需要指定圆心(点)和半径就可以了。那么,如果要画一个梯形呢?这里需要有点和连线。Path一般用来从某个点移动到另一个点连线。Path位于android.graphics包中。
方法或者属性名称 | 方法描述 |
lineTo(float x , float y) | 从最后点到指定点画线 |
moveTo(float x, float y) | 移动到指定点 |
reset() | 复位 |
3、绘制几何图形
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
//自定义视图类
private class MyView extends View{
public MyView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);//设置Canvas颜色
Paint paint = new Paint();//实例化Paint
paint.setAntiAlias(true);
paint.setColor(Color.RED);//设置颜色
paint.setStyle(Paint.Style.STROKE);//设置样式
paint.setStrokeWidth(3);//设置笔画粗细
canvas.drawCircle(40, 40, 30, paint);//画圆
canvas.drawRect(10, 90, 70, 150, paint);//画矩形
canvas.drawRect(10, 170, 70, 200, paint);//画矩形
RectF re = new RectF(10,220,70,250);//声明矩形
canvas.drawOval(re, paint);//画椭圆
Path path = new Path();//实例化路径
path.moveTo(10, 330);//移动到指定点
path.lineTo(70, 330);//画线
path.lineTo(40, 270);//画线
path.close();//关闭路径
canvas.drawPath(path, paint);//画路径
Path path1 = new Path();//实例化路径
path1.moveTo(10, 410);//移动到指定点
path1.lineTo(70, 410);//画线
path1.lineTo(55, 350);//画线
path1.lineTo(25, 350);//画线
path1.close();//关闭路径
canvas.drawPath(path1, paint);//画路径
paint.setStyle(Paint.Style.FILL);//设置样式
paint.setColor(Color.BLUE);//设置颜色
canvas.drawCircle(120, 40, 30, paint);//画圆
canvas.drawRect(90, 90, 150, 150, paint);//画矩形
canvas.drawRect(90, 170,150,200,paint);//画矩形
RectF re2 = new RectF(90,220,150,250);//实例化矩形
canvas.drawOval(re2, paint);//画椭圆
Path path2 = new Path();//实例化路径
path2.moveTo(90, 330);//移动到指定点
path2.lineTo(150, 330);//画线
path2.lineTo(120, 270);
path2.close();
canvas.drawPath(path2, paint);
Path path3 = new Path();
path3.moveTo(90, 410);
path3.lineTo(150, 410);
path3.lineTo(135, 350);
path3.lineTo(105, 350);
path3.close();
canvas.drawPath(path3, paint);
//线性渲染
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},
null,Shader.TileMode.REPEAT);
paint.setShader(mShader);//为Paint设置线性渲染
canvas.drawCircle(200, 40, 30, paint);
canvas.drawRect(170, 90, 230,150, paint);
canvas.drawRect(170, 170, 230, 200, paint);
RectF re3 = new RectF(170, 220, 230, 250);
canvas.drawOval(re3, paint);
Path path4 = new Path();
path4.moveTo(170, 330);
path4.lineTo(230, 330);
path4.lineTo(200, 270);
path4.close();
canvas.drawPath(path4, paint);
Path path5 = new Path();
path5.moveTo(170, 410);
path5.lineTo(230, 410);
path5.lineTo(215, 350);
path5.lineTo(185, 350);
path5.close();
canvas.drawPath(path5, paint);
paint.setTextSize(24);//设置文本大小
//写文字
canvas.drawText(getResources().getString(R.string.str_text1), 240, 50, paint);
canvas.drawText(getResources().getString(R.string.str_text2), 240, 120, paint);
canvas.drawText(getResources().getString(R.string.str_text3), 240, 190, paint);
canvas.drawText(getResources().getString(R.string.str_text4), 240, 250, paint);
canvas.drawText(getResources().getString(R.string.str_text5), 240, 320, paint);
canvas.drawText(getResources().getString(R.string.str_text6), 240, 390, paint);
}
}
}
四、图形特效
1、使用Matrix实现旋转、缩放和平移
该类具有3×3的矩阵坐标,通过该类可以实现图形的旋转、平移和缩放。使用日reset()方法来初始化矩阵类,使用setScale()、setTranslate()、setRotate()方法来设置矩阵缩放、平移和旋转属性。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView myView = new MyView(Main7Activity.this);
setContentView(myView);
}
class MyView extends View{
private Bitmap bm;//位图实例
private Matrix matrix = new Matrix();//Matrix实例
private float angle = 0.0f;//旋转角度
private int w,h;//位图宽和高
private float scale = 1.0f;//缩放比例
private boolean isScale = false;//判断缩放还是旋转
//构造方法
public MyView(Context context) {
super(context);
//获得位图
bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.image1);
w = bm.getWidth();//获得位图宽
h = bm.getHeight();//获得位图高
//使当前视图获得焦点
this.setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//重置Matrix
matrix.reset();
if(!isScale){
//旋转Matrix
matrix.setRotate(angle);
}else{
//缩放Matrix
matrix.setScale(scale, scale);
}
//根据原始位图和Matrix创建新视图
Bitmap bm2 = Bitmap.createBitmap(bm, 0, 0,w,h, matrix,true);
//绘制新视图
canvas.drawBitmap(bm2, matrix, null);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//向左旋转
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){//键盘←
isScale = false;
angle++;
postInvalidate();
}
//向右旋转
if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){//键盘→
isScale = false;
angle--;
postInvalidate();
}
//放大
if(keyCode == KeyEvent.KEYCODE_DPAD_UP){//键盘↑
isScale = true;
if(scale < 2.0)
scale += 0.1;
postInvalidate();
}
//缩小
if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){//键盘↓
isScale = true;
if(scale > 0.5)
scale -= 0.1;
postInvalidate();
}
return super.onKeyDown(keyCode, event);
}
}
}
2、使用Shader类渲染图形
Shader是一个抽象父类,其子类有多个,如BitmapShader(位图渲染)、ComposeShader(混合渲染)、LinearGradient(线性渲染)、RadialGradient(光束渲染)、SweepGradient(梯度渲染)等。通过Paint对象的paint.setShader(shader)方法来说使用Shader。
public class Main8Activity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView myView = new MyView(this);
setContentView(myView);
}
class MyView extends View{
//声明Bitmap对象
private Bitmap bm;
//声明位图渲染对象
private Shader bitmapShader;
//声明线性渲染对象
private Shader linearGradient;
//声明光束渲染对象
private Shader radiaGradient;
//声明梯度渲染对象
private Shader sweepGradient;
//声明混合渲染对象
private Shader composeShader;
//声明画笔
private Paint paint;
//声明颜色数组
private int[] colors;
private boolean isFirst = true;
public MyView(Context context) {
super(context);
//获得Bitmap实例
bm = BitmapFactory.decodeResource(getResources(), R.drawable.d101);
//实例化画笔
paint = new Paint();
colors = new int[]{Color.RED,Color.GREEN,Color.BLUE};
//实例化位图渲染对象,X坐标方向重复图形,Y坐标方向镜像图形
bitmapShader = new BitmapShader(bm, TileMode.REPEAT, TileMode.MIRROR);
//实例化线性渲染
linearGradient = new LinearGradient(0,0, 100, 100, colors, null, TileMode.REPEAT);
//实例化光束渲染
radiaGradient = new RadialGradient(100, 100, 80, colors, null, TileMode.REPEAT);
//实例化梯度渲染
sweepGradient = new SweepGradient(200, 200, colors, null);
//实例化混合渲染
composeShader = new ComposeShader(linearGradient, radiaGradient,PorterDuff.Mode.DARKEN);
//使其获得焦点
setFocusable(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(isFirst){
//写字,用来提示用户操作
String content = "按上/下/左/右/中间键测试!";
paint.setColor(Color.BLUE);
canvas.drawText(content, 0, content.length()-1, 20,20,paint);
}else{
//全屏画矩形
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
isFirst = false;
if(keyCode == KeyEvent.KEYCODE_DPAD_UP){
//将画笔渲染设置为位图渲染
paint.setShader(bitmapShader);
}
if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){
//将画笔渲染设置为线性渲染
paint.setShader(linearGradient);
}
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){
//将画笔渲染设置为光束渲染
paint.setShader(radiaGradient);
}
if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){
//将画笔渲染设置为梯度渲染
paint.setShader(sweepGradient);
}
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
//将画笔渲染设置为混合渲染
paint.setShader(composeShader);
}
//重绘界面
postInvalidate();
return super.onKeyDown(keyCode, event);
}
}
}