1、视图
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 > 7 8 <Button 9 android:id="@+id/bt_clear" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:text="清空" 13 /> 14 <com.zyhui.zyhsurfaceview.ZyhSurfaceView 15 android:id="@+id/zyh_sfv" 16 android:layout_width="match_parent" 17 android:layout_height="match_parent" 18 /> 19 20 </LinearLayout>
2、MainActivity
1 package com.zyhui.zyhsurfaceview; 2 3 import android.os.Bundle; 4 import android.view.View; 5 import android.view.View.OnClickListener; 6 import android.widget.Button; 7 import android.app.Activity; 8 9 public class MainActivity extends Activity implements OnClickListener { 10 11 private ZyhSurfaceView zyh_sfv; 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 zyh_sfv = (ZyhSurfaceView) findViewById(R.id.zyh_sfv); 18 Button button = (Button) findViewById(R.id.bt_clear); 19 button.setOnClickListener(this); 20 } 21 22 @Override 23 public void onClick(View v) { 24 zyh_sfv.clear(); 25 } 26 27 }
3、自定义surfaceView控件
1 package com.zyhui.zyhsurfaceview; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Random; 6 7 import android.content.Context; 8 import android.graphics.Bitmap; 9 import android.graphics.BitmapFactory; 10 import android.graphics.Canvas; 11 import android.graphics.Color; 12 import android.graphics.Paint; 13 import android.os.Handler; 14 import android.os.HandlerThread; 15 import android.os.Message; 16 import android.util.AttributeSet; 17 import android.util.Log; 18 import android.view.MotionEvent; 19 import android.view.SurfaceHolder; 20 import android.view.SurfaceHolder.Callback; 21 import android.view.SurfaceView; 22 23 //==================================== 24 //1、继承SurfaceView 25 //2、监听SurfaceView的生命周期 26 //3、自定义线程 27 //4、自定义线程需要的参数 28 //5、监听线程的生命周期 29 //6、通过SurfaceView的生命周期来执行我们的线程 30 //7、添加触摸事件 31 // 32 //主要是通过线程把图片画进holder中,这样它就会显示出来; 33 //如果直接在HandlerThread线程中更新ui控件是不行,它会报错的 34 //==================================== 35 public class ZyhSurfaceView extends SurfaceView implements Callback { 36 37 private DrawingThread drawingThread; 38 39 public ZyhSurfaceView(Context context, AttributeSet attrs) { 40 super(context, attrs); 41 initParams(); 42 } 43 44 public ZyhSurfaceView(Context context) { 45 super(context); 46 initParams(); 47 } 48 49 private void initParams(){ 50 //监听SurfaceView的生命周期 51 getHolder().addCallback(this); 52 } 53 54 @Override 55 public void surfaceCreated(SurfaceHolder holder) { 56 drawingThread = new DrawingThread(getHolder(), 57 BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)); 58 drawingThread.start(); 59 } 60 61 @Override 62 public void surfaceChanged(SurfaceHolder holder, int format, int width, 63 int height) { 64 //Log.i("zyh", width + "-----" + height); 65 this.drawingThread.updateSize(width, height);//更新宽和高 66 } 67 68 @Override 69 public void surfaceDestroyed(SurfaceHolder holder) { 70 this.drawingThread.quit(); 71 this.drawingThread = null; 72 } 73 74 @Override 75 public boolean onTouchEvent(MotionEvent event) { 76 if(event.getAction() == MotionEvent.ACTION_DOWN){ 77 this.drawingThread.addItem(event.getX(), event.getY()); 78 } 79 return super.onTouchEvent(event); 80 } 81 82 //清空图片 83 public void clear(){ 84 this.drawingThread.clear(); 85 } 86 87 //自定义线程 88 private class DrawingThread extends HandlerThread implements android.os.Handler.Callback{ 89 private static final int MSG_ADD = 101;//添加消息 90 private static final int MSG_MOVE = 102;//消息移动 91 private static final int MSG_CLEAR = 103;//清空 92 93 //定义SurfaceView的宽和高 94 private int drawingWidth,drawingHeight; 95 96 //缓存视图 97 private SurfaceHolder drawingHolder; 98 //画笔 99 private Paint paint; 100 //需要绘制的图片 101 private Bitmap iconBitmap; 102 //图片对象数组 103 private List<DrawingItem> locations; 104 //更新ui的Handler 105 private Handler receiver; 106 //线程是否在运行 107 private boolean isRunning = false; 108 109 public DrawingThread(SurfaceHolder drawingHolder, Bitmap bitmap) { 110 super("DrawingThread"); 111 this.drawingHolder = drawingHolder; 112 this.iconBitmap = bitmap; 113 this.locations = new ArrayList<DrawingItem>(); 114 this.paint = new Paint(Paint.ANTI_ALIAS_FLAG); 115 } 116 117 //监听线程的生命周期 118 @Override 119 protected void onLooperPrepared() { 120 super.onLooperPrepared(); 121 this.receiver = new Handler(getLooper(),this); 122 this.isRunning = true; 123 this.receiver.sendEmptyMessage(MSG_ADD); 124 } 125 126 @Override 127 public boolean quit() { 128 this.isRunning = false; 129 this.receiver.removeCallbacksAndMessages(null);//移除消息 130 return super.quit(); 131 } 132 133 public void updateSize(int width, int height){ 134 this.drawingWidth = width; 135 this.drawingHeight = height; 136 } 137 138 public void addItem(float x, float y){ 139 Message msg = Message.obtain(receiver, MSG_ADD, (int)x, (int)y); 140 this.receiver.sendMessage(msg ); 141 } 142 143 public void clear(){ 144 this.receiver.sendEmptyMessage(MSG_CLEAR); 145 } 146 147 private class DrawingItem{ 148 private int x,y; 149 private boolean isVertical,isHorizontal; 150 public DrawingItem(int x, int y, boolean isVertical, 151 boolean isHorizontal) { 152 this.x = x; 153 this.y = y; 154 this.isVertical = isVertical; 155 this.isHorizontal = isHorizontal; 156 } 157 158 } 159 160 @Override 161 public boolean handleMessage(Message msg) { 162 switch(msg.what){ 163 case MSG_ADD: 164 Random random = new Random(); 165 DrawingItem drawingItem = new DrawingItem(msg.arg1,msg.arg2, 166 random.nextBoolean(),random.nextBoolean()); 167 locations.add(drawingItem); 168 break; 169 case MSG_MOVE: 170 if(!isRunning){ 171 return true; 172 } 173 //获取枷锁画布 174 Canvas lockCanvas = this.drawingHolder.lockCanvas(); 175 if(lockCanvas == null){ 176 break; 177 } 178 lockCanvas.drawColor(Color.BLACK); 179 for(DrawingItem item : locations){ 180 item.x += item.isHorizontal ? 5 : -5; 181 if(item.x > this.drawingWidth - iconBitmap.getWidth()){ 182 item.isHorizontal = false; 183 }else{ 184 item.isHorizontal = true; 185 } 186 187 item.y += item.isVertical ? 5 : -5; 188 if(item.y > this.drawingHeight - iconBitmap.getHeight()){ 189 item.isVertical = false; 190 }else{ 191 item.isVertical = true; 192 } 193 194 //绘图 195 lockCanvas.drawBitmap(iconBitmap, item.x, item.y, paint); 196 } 197 198 this.drawingHolder.unlockCanvasAndPost(lockCanvas);//释放 199 //Log.i("zyh", Thread.currentThread().getName()); 200 break; 201 case MSG_CLEAR: 202 //清空图片 203 locations.clear(); 204 break; 205 default: 206 break; 207 } 208 209 if(isRunning){ 210 this.receiver.sendEmptyMessage(MSG_MOVE);//促使图片的移动 211 } 212 return false; 213 } 214 } 215 }
时间: 2024-12-15 16:00:51