前面说到了画图,其实更好的就是使用 surfaceView了。
surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface,
对于一个View的onDraw()方法,不能够满足将其移动到后台线程中去。因为从后台线程修改一个GUI元素会被显式地禁止的。当需要快速地更新View的UI,或者当前渲染代码阻塞GUI线程的时间过长的时候,SurfaceView就是解决上述问题的最佳选择。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的操作,或者那些要求快速更新或者高速帧率的地方,例如使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。
可以直接从内存或硬件设备比如相机等取得图像数据,是个非常重要的绘图容器。它的特性是:可以在主线程之外的线程中向屏幕绘图。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。绘制的东西直接复制到显存从而显示出来,这使得显示速度会非常快,而在Surface 被销毁之前必须结束。
下面给个简单的例子,就是不停的绘制 ,这样按照前面说的,就可以再 上面绘制各种自己想要的效果了:
public class SurfaceDraw extends Activity{
private SurfaceView sf;
private SurfaceHolder sfh; //surfaceView的 控制器
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw);
sf = (SurfaceView) this.findViewById(R.id.SurfaceView01);
//得到控制器
sfh = sf.getHolder();
//对 surfaceView 进行操作
sfh.addCallback(new DoThings());// 自动运行surfaceCreated以及surfaceChanged
}
private class DoThings implements SurfaceHolder.Callback{
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//在surface的大小发生改变时激发
System.out.println("surfaceChanged");
}
@Override
public void surfaceCreated(SurfaceHolder holder){
new Thread(){
public void run() {
while(true){
//1.这里就是核心了, 得到画布 ,然后在你的画布上画出要显示的内容
Canvas c = sfh.lockCanvas(new Rect(0, 0, 200, 200));
//2.开画
Paint p =new Paint();
p.setColor(Color.rgb( (int)(Math.random() * 255),
(int)(Math.random() * 255) , (int)(Math.random() * 255)));
Rect aa = new Rect( (int)(Math.random() * 100) ,
(int)(Math.random() * 100)
,(int)(Math.random() * 500)
,(int)(Math.random() * 500) );
c.drawRect(aa, p);
//3. 解锁画布 更新提交屏幕显示内容
sfh.unlockCanvasAndPost(c);
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
};
}.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//销毁时激发,一般在这里将画图的线程停止、释放。
System.out.println("surfaceDestroyed==");
}
}
}
public class Drag extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DragImage view=new DragImage(this);
setContentView(view);
}
private class DragImage extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener{
private Context context;
private SurfaceHolder holder;
private Bitmap icon;
private Paint paint;
private boolean running=true;
public DragImage(Context context) {
super(context);
this.context=context;
holder = this.getHolder();//获取holder
holder.addCallback(this);
this.setOnTouchListener(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.wuranl_1);
paint=new Paint();
running=true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
running=false;
}
@Override
public void run() {
int SLEEP_TIME=100;
while (running) {
//开始画的时间 long start=System.currentTimeMillis();
Canvas canvas = holder.lockCanvas();//获取画布
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(icon, rect.left,rect.top,null);
holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像
//结束的时间 long end=System.currentTimeMillis();
}
}
// Region region=new Region();
private Point point=new Point();//点击点
private Rect rect;//图片的rect
private boolean canDrag=false;//判断是否点击在图片上,否则拖动无效
private int offsetX=0,offsetY=0;//点击点离图片左上角的距离
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
//手按下的时候
case MotionEvent.ACTION_DOWN:
point.x=(int)event.getX();
point.y=(int)event.getY();
if(rect.contains(point.x, point.y)){
canDrag=true;
offsetX=point.x-rect.left;
offsetY=point.y-rect.top;
}
break;
//移动的时候
case MotionEvent.ACTION_MOVE:
if(canDrag){
rect.left=(int)event.getX()-offsetX;
rect.top=(int)event.getY()-offsetY;
rect.right=rect.left+icon.getWidth();
rect.bottom=rect.top+icon.getHeight();
if (rect.left < 0) {
rect.left = 0;
rect.right = rect.left+icon.getWidth();
}
if (rect.right > getMeasuredWidth()) {
rect.right = getMeasuredWidth();
rect.left = rect.right-icon.getWidth();
}
if (rect.top < 0) {
rect.top = 0;
rect.bottom = rect.top+icon.getHeight();
}
if (rect.bottom > getMeasuredHeight()) {
rect.bottom = getMeasuredHeight();
rect.top = rect.bottom-icon.getHeight();
}
}
break;
case MotionEvent.ACTION_UP:
canDrag=false;
break;
default:
break;
}
return true;
}
}
}
还有前面在 View上面绘制的动态折线图,在surfaceView上效果也更好呢