博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]Android中在SurfaceView上高效绘图
阅读量:6079 次
发布时间:2019-06-20

本文共 2961 字,大约阅读时间需要 9 分钟。

本文转自:

Android的大多数控件都是继承自View的,因此在自定义控件时一般也是继承View类,但是对于高效的,游戏级别的绘图,或者是播放器等要求比较高的地方,普通的View类就

有点吃不开了,这个时候就要用到SurfaceView类。

因为比较高级,所以就该装B,单纯一个继承自SurfaceView类是不行的,必须实现一个SurfaceHolder.Callback接口来指明SurfaceView创建、改变、删除时的回调方法,并且

在SurfaceView中通过一个SurfaceHolder对象来控制SurfaceView。

如果将该SurfaceView作为某个Activity的全屏View,则直接调用setContentView(new MyView());就好了;但若是作为屏幕View的一部份,就应该修改对应的layout XML文件

了,添加类似的布局代码:

    <com.example.fq.MyView
    android:id="@+id/sv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
其中com.example.fq.MyView为对应自定义类的全名。
由于默认的XML文件解析方法是调用View的View(Context , AttributeSet )构造函数构造View,因此你的自定义SurfaceView中也应该有一个参数为(Context , AttributeSet )

的构造函数,并且在构造函数中执行父类的对应函数super( Context , AttributeSet )。

在绘图时,必须首先用Canvas c=holder.lockCanvas();锁定并获得画布,随后进行绘制,再调用holder.unlockCanvasAndPost(c);将绘制内容进行呈现

下面是个例子:

MyView.java:
public class MyView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder=null; //控制对象
private Vector<Float> xs=new Vector<Float>();
private Vector<Float> ys=new Vector<Float>();

public MyView(Context context,AttributeSet attr) {

   super(context,attr);
   // TODO Auto-generated constructor stub
   holder=getHolder();
   holder.addCallback(this);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height) {
   // TODO Auto-generated method stub

}

@Override

public void surfaceCreated(SurfaceHolder holder) {
   // TODO Auto-generated method stub
   new Thread(new MyLoop()).start();
}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {
   // TODO Auto-generated method stub

}

public void doDraw(Canvas canvas) {

   // TODO Auto-generated method stub
   super.onDraw(canvas);
   canvas.drawColor(Color.WHITE);//这里是绘制背景
   Paint p=new Paint(); //笔触
   p.setAntiAlias(true); //反锯齿
   p.setColor(Color.BLACK);
   p.setStyle(Style.STROKE);
   for(int i=0;i<xs.size();i++)
    canvas.drawCircle(xs.elementAt(i),ys.elementAt(i),10, p);
}

@Override

public boolean onTouchEvent(MotionEvent event) {
   // TODO Auto-generated method stub
   if(event.getAction()==MotionEvent.ACTION_DOWN){
    xs.add(event.getX());
    ys.add(event.getY());
   }
   return true;
}
class MyLoop implements Runnable{
//熟悉游戏编程的应该很面熟吧,主循环
   @Override
   public void run() {
    // TODO Auto-generated method stub
    while(true){
     try{
      Canvas c=holder.lockCanvas();
      doDraw(c);
      holder.unlockCanvasAndPost(c);
      Thread.sleep(20);
     }catch(Exception e){
     
     }
    }
   }
  
}

}

Main.java

public class Main extends Activity {
private MyView sv=null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sv=(MyView)findViewById(R.id.sv);
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <com.example.fq.MyView
    android:id="@+id/sv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
</LinearLayout>

 

 

转载地址:http://enhgx.baihongyu.com/

你可能感兴趣的文章
MySQL数据库导入导出常用命令
查看>>
低版本Samba无法挂载
查看>>
Telegraf+Influxdb+Grafana构建监控平台
查看>>
使用excel 展现数据库内容
查看>>
C#方法拓展
查看>>
MySql.Data.dll的版本
查看>>
Linux系统磁盘管理
查看>>
hdu 2191 (多重背包+二进制优化)
查看>>
home.php
查看>>
neo4j---删除关系和节点
查看>>
redis分布式锁redisson
查看>>
什么样的企业可以称之为初创企业?
查看>>
Python爬虫之BeautifulSoup
查看>>
《HTML 5与CSS 3权威指南(第3版·下册)》——第20章 使用选择器在页面中插入内容...
查看>>
如何判断自己适不适合做程序员?这几个特点了解一下
查看>>
newinstance()和new有什么区别
查看>>
android下载封装类
查看>>
[node] 用 node-webkit 开发桌面应用
查看>>
Nginx访问控制和虚拟主机
查看>>
report widget not working for external users
查看>>