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来获取画布
surfaceView画图的更多相关文章
- SurfaceView 使用demo 飞机游戏小样
本demo 主要使用了surfaceview 画图. 1.在线程中对canvas操作. 2.实现画图 3.surfaceView 继承了view 可以重写ontouchevent方法来操作输入. 代码 ...
- 如何自学Android--转
原文地址:http://blog.csdn.net/lavor_zl/article/details/51217319 1. Java知识储备 本知识点不做重点讲解: 对于有基础的同学推荐看<J ...
- Android 涂鸦最佳实践
Android中实现手势画图一般都两种方式,一是直接在View上绘制,而是使用SurfaceView. 两者还是有一些差别的.简介下. View:显示视图,内置画布,提供图形绘制函数.触屏事件.按键事 ...
- 如何自学 Android 的?
http://android.jobbole.com/83380/ 1. Java知识储备 本知识点不做重点讲解:对于有基础的同学推荐看<Java编程思想>,巩固基础,查漏补全,了解并熟悉 ...
- Android如何自学----转自lavor从segmentfault
如何自学Android 1. Java知识储备 本知识点不做重点讲解: 对于有基础的同学推荐看<Java编程思想>,巩固基础,查漏补全,了解并熟悉更多细节知识点. 对于没有基础的同学推荐看 ...
- Android代码速查,写给新手的朋友们[转]
原文地址:http://www.open-open.com/lib/view/open1397286499090.html 0 android 创建按钮 Button button = new But ...
- Android SurfaceView实现静态于动态画图效果
本文是基于Android的SurfaceView的动态画图效果,实现静态和动态下的正弦波画图,可作为自己做图的简单参考,废话不多说,先上图, 静态效果: 动态效果: 比较简单,代码注释的也比较详细,易 ...
- android surfaceView 的简单使用 画图,拖动效果
前面说到了画图,其实更好的就是使用 surfaceView了. surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface, 对于一个View的onDraw()方法 ...
- Android 画图类View与SurfaceView之学习
在开发游戏开发中,android相应的提供了几个重要的模块: 1.显示界面的视图: Android 提供 View 和 SurfaceView 2.控制游戏整体结构: android 提供 Acti ...
随机推荐
- 过拟合/欠拟合&logistic回归等总结(Ng第二课)
昨天学习完了Ng的第二课,总结如下: 过拟合:欠拟合: 参数学习算法:非参数学习算法 局部加权回归 KD tree 最小二乘 中心极限定律 感知器算法 sigmod函数 梯度下降/梯度上升 二元分类 ...
- How many prime numbers(求素数个数)
How many prime numbers Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- linux64位系统中g++4.4.7下使用wcsncpy函数有造成段错误的BUG(其它g++版本号未知)
一.描写叙述 眼下已经linux64位系统中g++4.4.7下发现了该bug.其它的版本号还未測试. 经測试,假设传入wcsncpy函数第一个參数(即目标缓冲区)的地址不能被4整除的话就必然会发生段错 ...
- vmware 几种联网的方式,怎样实现虚拟机上网
我的pc有一个IP地址是可以訪问网络的,那么如何让VM可以共享我的IP地址,也能上网呢.今天在摸索中实现了,详细的配置例如以下: 1,首先将VM的网卡net8启用: 2,然后将VM的网卡设置为VMne ...
- Ext JS学习第十天 Ext基础之动态加载JS文件(补充)
此文用来记录学习笔记: •Ext4.x版本提供的一大亮点就是Ext.Loader这个类的动态加载机制!只要遵循路径规范,即可动态加载js文件,方便把自己扩展组件动态加载进来,并且减轻浏览器的压力. • ...
- C#中析构函数,命名空间及字符串的运用(Ninth day)
又到了总结知识的时间了,今天在云和学院学习了析构函数,命名空间及字符串的处理,现在就为大家总结下来. 理论: 析构函数 不能在结构中定义析构函数.只能对类使用析构函数. 一个类只能有一个析构函数. 无 ...
- ThinkPHP - 事务操作
/* * 添加酒店和房型 * */ public function insertAll($arr_hotel=array(),$arr_room=array()){ $model = new Mode ...
- mysql 表及其列字符集设置
--修改表的字符集 alter table rtb_media_daily_report character set gbk; --查询表列字符集 show full columns from rtb ...
- HTTP status codes
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行.响应码分五种类型,由它们的第一位数字表示:1.1xx:信息,请求收到,继续处理2.2xx:成功,行为被成功地接受.理解和采纳3 ...
- Nginx阅读笔记(四)之root和alias
nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri ...