surfaceView画图

时间:2023-03-08 20:32:12
surfaceView画图

1、视图

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <Button
android:id="@+id/bt_clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空"
/>
<com.zyhui.zyhsurfaceview.ZyhSurfaceView
android:id="@+id/zyh_sfv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/> </LinearLayout>

2、MainActivity

 package com.zyhui.zyhsurfaceview;

 import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity; public class MainActivity extends Activity implements OnClickListener { private ZyhSurfaceView zyh_sfv; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
zyh_sfv = (ZyhSurfaceView) findViewById(R.id.zyh_sfv);
Button button = (Button) findViewById(R.id.bt_clear);
button.setOnClickListener(this);
} @Override
public void onClick(View v) {
zyh_sfv.clear();
} }

3、自定义surfaceView控件

 package com.zyhui.zyhsurfaceview;

 import java.util.ArrayList;
import java.util.List;
import java.util.Random; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView; //====================================
//1、继承SurfaceView
//2、监听SurfaceView的生命周期
//3、自定义线程
//4、自定义线程需要的参数
//5、监听线程的生命周期
//6、通过SurfaceView的生命周期来执行我们的线程
//7、添加触摸事件
//
//主要是通过线程把图片画进holder中,这样它就会显示出来;
//如果直接在HandlerThread线程中更新ui控件是不行,它会报错的
//====================================
public class ZyhSurfaceView extends SurfaceView implements Callback { private DrawingThread drawingThread; public ZyhSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initParams();
} public ZyhSurfaceView(Context context) {
super(context);
initParams();
} private void initParams(){
//监听SurfaceView的生命周期
getHolder().addCallback(this);
} @Override
public void surfaceCreated(SurfaceHolder holder) {
drawingThread = new DrawingThread(getHolder(),
BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
drawingThread.start();
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//Log.i("zyh", width + "-----" + height);
this.drawingThread.updateSize(width, height);//更新宽和高
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.drawingThread.quit();
this.drawingThread = null;
} @Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
this.drawingThread.addItem(event.getX(), event.getY());
}
return super.onTouchEvent(event);
} //清空图片
public void clear(){
this.drawingThread.clear();
} //自定义线程
private class DrawingThread extends HandlerThread implements android.os.Handler.Callback{
private static final int MSG_ADD = 101;//添加消息
private static final int MSG_MOVE = 102;//消息移动
private static final int MSG_CLEAR = 103;//清空 //定义SurfaceView的宽和高
private int drawingWidth,drawingHeight; //缓存视图
private SurfaceHolder drawingHolder;
//画笔
private Paint paint;
//需要绘制的图片
private Bitmap iconBitmap;
//图片对象数组
private List<DrawingItem> locations;
//更新ui的Handler
private Handler receiver;
//线程是否在运行
private boolean isRunning = false; public DrawingThread(SurfaceHolder drawingHolder, Bitmap bitmap) {
super("DrawingThread");
this.drawingHolder = drawingHolder;
this.iconBitmap = bitmap;
this.locations = new ArrayList<DrawingItem>();
this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
} //监听线程的生命周期
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
this.receiver = new Handler(getLooper(),this);
this.isRunning = true;
this.receiver.sendEmptyMessage(MSG_ADD);
} @Override
public boolean quit() {
this.isRunning = false;
this.receiver.removeCallbacksAndMessages(null);//移除消息
return super.quit();
} public void updateSize(int width, int height){
this.drawingWidth = width;
this.drawingHeight = height;
} public void addItem(float x, float y){
Message msg = Message.obtain(receiver, MSG_ADD, (int)x, (int)y);
this.receiver.sendMessage(msg );
} public void clear(){
this.receiver.sendEmptyMessage(MSG_CLEAR);
} private class DrawingItem{
private int x,y;
private boolean isVertical,isHorizontal;
public DrawingItem(int x, int y, boolean isVertical,
boolean isHorizontal) {
this.x = x;
this.y = y;
this.isVertical = isVertical;
this.isHorizontal = isHorizontal;
} } @Override
public boolean handleMessage(Message msg) {
switch(msg.what){
case MSG_ADD:
Random random = new Random();
DrawingItem drawingItem = new DrawingItem(msg.arg1,msg.arg2,
random.nextBoolean(),random.nextBoolean());
locations.add(drawingItem);
break;
case MSG_MOVE:
if(!isRunning){
return true;
}
//获取枷锁画布
Canvas lockCanvas = this.drawingHolder.lockCanvas();
if(lockCanvas == null){
break;
}
lockCanvas.drawColor(Color.BLACK);
for(DrawingItem item : locations){
item.x += item.isHorizontal ? 5 : -5;
if(item.x > this.drawingWidth - iconBitmap.getWidth()){
item.isHorizontal = false;
}else{
item.isHorizontal = true;
} item.y += item.isVertical ? 5 : -5;
if(item.y > this.drawingHeight - iconBitmap.getHeight()){
item.isVertical = false;
}else{
item.isVertical = true;
} //绘图
lockCanvas.drawBitmap(iconBitmap, item.x, item.y, paint);
} this.drawingHolder.unlockCanvasAndPost(lockCanvas);//释放
//Log.i("zyh", Thread.currentThread().getName());
break;
case MSG_CLEAR:
//清空图片
locations.clear();
break;
default:
break;
} if(isRunning){
this.receiver.sendEmptyMessage(MSG_MOVE);//促使图片的移动
}
return false;
}
}
}

//画图程序:handleMessage
//画出的图之所以能够显示是因为通过SurfaceView的holder来获取画布