Android里面画图用到的一些相关的东西有:View,Canvas,Paint,Bitmap。
一,View是画图的目的地,也是直接展现给用户的接口;
二,Canvas是画笔(与J2ME里的Canvas不一样,跟像J2ME里的Graphics),提供了drawText, drawRect, drawPicture等各种画图方法。既然有“画笔”,就必然还有“画布”。Canvas这个单词本身有画布的意思,但是此处被赋予了“画笔”的作用,那么Android里的“画布”究竟是什么呢?答案是:Bitmap。Bitmap直译是“位图”的意思,在Android中它除了作为图像,还被用作“画布”。因为图像(Image)有Immutable(不可变的)和Mutable(可变的)之分。创建自图形文件的Bitmap是imutable,只给定宽高以及其他一些参数创建的Bitmap则是mutable。画布由于其内容会随着画笔的动作而更改,所以画布都是使用mutable Bitmap。
//Imutalbe bitmap Bitmap temp = BitmapFactory.decodeFile("/sdcard/zgr.jpg"); Bitmap immutalbe = Bitmap.createBitmap(temp); //Mutable Bitmap mutalbe = Bitmap.createBitmap(240, 320, Bitmap.Config.RGB_565);
三,Paint可以理解为画笔属性的设置。比如颜色,消除锯齿等等。
四,Bitmap在前面已经有了一些介绍,关于创建mutable Bitmap所用到的Bitmap.Config里的设定的详细介绍再讨论。
以下写了一个例子,功能是在触摸屏幕时在触摸处画点。
package com.cim; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.media.MediaPlayer; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; public class Test extends Activity { MediaPlayer player = null; OnTouchListener touchListener = new OnTouchListener(){ public boolean onTouch(View v, MotionEvent e) { if(e.getAction() == MotionEvent.ACTION_DOWN){ player.start(); System.out.println("OnTouch!!"); } return false; } }; private OnClickListener clickListener = new OnClickListener(){ @Override public void onClick(View v) { if(player != null) player.start(); System.out.println("OnClike!!"); } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); MyView view = new MyView(this); setContentView(view); view.requestFocus(); player = MediaPlayer.create(this, R.raw.hello); // View button = findViewById(R.id.Button); // button.setOnClickListener(clickListener); // button.setOnTouchListener(touchListener); } } class MyView extends View{ private Paint mPaint; private Bitmap mBitmap; private Bitmap srcBitmap; public MyView(Context context) { super(context); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setARGB(0, 0xff, 0, 0); mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.RGB_565); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(mBitmap != null) canvas.drawBitmap(mBitmap, 0, 0, null); } @Override public boolean onTouchEvent(MotionEvent event) { int N = event.getHistorySize(); float x = 0; float y = 0; float press = event.getPressure(); x = /*event.getXPrecision() * */event.getX(); y = /*event.getYPrecision() * */event.getY(); System.out.println(">>>VIEW: N = " + N); System.out.println(">>>VIEW: X = " + event.getX() + " Y = " + event.getY()); System.out.println(">>>VIEW: Press = " + event.getPressure() + " Size = " + event.getSize()); System.out.println(">>>VIEW: XPre = " + event.getXPrecision() + " YPre = " + event.getYPrecision()); System.out.println(">>>VIEW: X * XPre = " + x + " Y * YPre = " + y); for(int i = 0; i < N; i++){ System.out.println(">>>VIEW: i = " + i + " Xhis = " + event.getHistoricalX(i) + " Yhis = " + event.getHistoricalY(i)); System.out.println(">>>VIEW: Pressure: " + event.getHistoricalPressure(i) + " size: " + event.getHistoricalSize(i)); } Canvas canvas = new Canvas(); canvas.setBitmap(mBitmap); //mPaint.setARGB((int) (255 * press), 0xff, 0, 0); mPaint.setARGB(100, 0xff, 0, 0); canvas.drawCircle(x, y, 4, mPaint); mPaint.setARGB(255, 0, 0xff, 0); canvas.drawCircle(x + 4, y, 4, mPaint); mPaint.setARGB(200, 0, 0, 0xff); canvas.drawCircle(x, y + 4, 4, mPaint); invalidate((int)(x - 4), (int)(y - 4), (int)(x + 8), (int)(y + 8)); return true; } }
需要注意:每次调用触屏事件进行画点动作时,都需要调用invaliddate(rect)方法来出发OnDraw(canvas)函数进行重画。因为OnTouchEvent()函数只是将点画到了mBitmap上,而非与用户交互的View上;要给用户显示实时的效果,必须激发OnDraw()函数才行。