Android中的图形图像
一、在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"
- <strong><u>android:src="@drawable/image1"</u></strong> />
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);
- }
- }
- }