可不可以用surfaceview camera画出这种界面

查看: 1514|回复: 18
可不可以用Surfaceview画出这种界面啊?
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
就是先画出这种网格背景,然后在这个背景上每次再画出一部分线条,最好当触摸屏幕的时候,再用另一种颜色画一条竖线,这样就知道触摸到哪个地方了。
点很近的话本来就会重合啊,你只要在放大时给它们适当的距离就好了.你难道认为可以超出屏幕分辨率极限来表示数据吗
该用户从未签到主题帖子e币
做运算,做完运算才变成float型的
点很近的话本来就会重合啊,你只要在放大时给它们适当的距离就好了.你难道认为可以超出屏幕分辨率极限来表示数据吗
签到天数: 1 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
重点是怎么弄啊?&
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
本帖子中包含更多资源
才可以下载或查看,没有帐号?
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
重点是怎么弄啊?
签到天数: 1 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
必须可以~~锁定点击位置的一块脏区域,绘制就可以了嘛,在提交就行了
不会出现覆盖什么的这种问题吗?我对覆盖这块还不太了解&
不会出现覆盖什么的这种问题吗?我对覆盖这块还不太了解&
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
必须可以~~锁定点击位置的一块脏区域,绘制就可以了嘛,在提交就行了
不会出现覆盖什么的这种问题吗?我对覆盖这块还不太了解
网上有很多讲解,看看嘛,很简单的,就是实现个接口,这样自己不又向大神靠近了一步嘛,看看吧&
该用户从未签到主题帖子e币
马克一下 看有没有解决的
签到天数: 1 天连续签到: 1 天[LV.1]初来乍到主题帖子e币
不会出现覆盖什么的这种问题吗?我对覆盖这块还不太了解
网上有很多讲解,看看嘛,很简单的,就是实现个接口,这样自己不又向大神靠近了一步嘛,看看吧
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
必须可以~~锁定点击位置的一块脏区域,绘制就可以了嘛,在提交就行了
不会出现覆盖什么的这种问题吗?我对覆盖这块还不太了解
该用户从未签到主题帖子e币
马克一下 看有没有解决的
该用户从未签到主题帖子e币
就是覆盖了也没有什么啊,不是画在原来的位置吗?一般画背景的要求是surfacechanged中画就可以了,而需要改变的部分直接获得Canvas canvas = holder.lockcanvas()后直接画就可以了。消除上一次的触摸线条在上次触摸的区域重新刷新画一下不就可以了?
哪有那么容易啊!其实是在网格坐标系为背景的基础上,逐步延伸画出一段连续的波形,也就是每次画一小段,波形是连续的,画到头后就将波形清除,但保留坐标系背景,再重新从头开始画起。&
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
就是覆盖了也没有什么啊,不是画在原来的位置吗?一般画背景的要求是surfacechanged中画就可以了,而需要改变 ...
哪有那么容易啊!其实是在网格坐标系为背景的基础上,逐步延伸画出一段连续的波形,也就是每次画一小段,波形是连续的,画到头后就将波形清除,但保留坐标系背景,再重新从头开始画起。
看不出有什么难的,surface你可以看成是屏幕表面,你只要在surface创建,改变时重新画一遍背景和保存下来的曲线数据就可以了,当你判断波形数据已经充满你定义的对应屏幕的数组时,重新画一遍背景,把旧数据从数组之类的中&
该用户从未签到主题帖子e币
哪有那么容易啊!其实是在网格坐标系为背景的基础上,逐步延伸画出一段连续的波形,也就是每次画一小段, ...
看不出有什么难的,surface你可以看成是屏幕表面,你只要在surface创建,改变时重新画一遍背景和保存下来的曲线数据就可以了,当你判断波形数据已经充满你定义的对应屏幕的数组时,重新画一遍背景,把旧数据从数组之类的中清空,把新数据保存进去并画出来就可以了.
不会闪屏么?也就是每次都要回复成背景色,黑一下,然后才又重新开始画图。而且如果每次更新都要画全部内容的话,那用View不就行了,而且用View还不会闪屏。&
签到天数: 220 天连续签到: 1 天[LV.7]常住居民III主题帖子e币
看不出有什么难的,surface你可以看成是屏幕表面,你只要在surface创建,改变时重新画一遍背景和保存下来的 ...
不会闪屏么?也就是每次都要回复成背景色,黑一下,然后才又重新开始画图。而且如果每次更新都要画全部内容的话,那用View不就行了,而且用View还不会闪屏。
QQ已认证,此人靠谱
推荐阅读热门话题
619991866415415378323273272257254249224215210715
23&分钟前1&小时前3&小时前4&小时前4&小时前16&小时前昨天&23:52昨天&17:12昨天&17:06昨天&16:39昨天&15:34昨天&15:31昨天&15:19昨天&14:24昨天&11:33昨天&10:49
Powered byandroid surfaceview 画上黑色还能让他透明吗_百度知道
android surfaceview 画上黑色还能让他透明吗
  SurfaceView 是View的继承类,这个视图里内嵌了一个专门用于绘制的Surface。可以控制这个Surface的格式和尺寸。SurfaceView控制这个Surface的绘制位置  SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类上使用双缓冲机制,在新的线程中更新画面所以新界面速度比view快。  Surface是纵深排序的,这说明它总在自己所在的窗口的后面。SurfaceView 提供了一个可见区域,只有在这个可见区域内的surface部分内容才可见,可见区域外部部分不可 见。surface的排版显示受到视图层级关系的影响,它的兄弟节点会在顶端显示。这意味者surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如:文本和按钮等控件)。但是,当surface上面有透明控件时,它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口  Surfaceview变的可见时,surface被创建,surfaceView隐藏前,surface被毁灭。这样可以节省资源。surface创建:surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder).  SurfaceView的核心提供了两个线程:UI线程和渲染线程。应该注意的是:  a.所有的SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序的主线程。渲染线程所要访问的各种变量应该做同步处理。  b.由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHoledr.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效地surface.  二、SurfaceView类 和View类的区别  SurfaceView 和View的最本质的区别在于,surfaceView是在一个在新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面,可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞,那么将无法响应按键,触摸等消息。当使用surfaceView由于是在新的线程中更新画面所以不会阻塞你的UI主线程,但是这也会有另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这样就会有点复杂了。  View:必须在UI的主线程中更新画面,用于被动更新画面。  surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。  所以在游戏的应用上,根据游戏的特点,一般分为两类:  a. 被动更新画面的。比如棋类,这种用view就好。因为画面的跟新依赖于onTouch来更新,可以直接使用invalidate.因为这种情况下,这一次Touch和下一次Touch需要的时间比较长些,不会产生  影响。  b.主动更新:比如一个人在一直跑动。这就需要一个单独的thread不停地重绘人的转台,避免阻塞mian UI Thread 。所以显然view 不适合,需要surfaceView来控制。  (1.)定义:  可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。  它的特性:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重时造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。  SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用窗体不见的应用使用的。Android系统中一个重要的概念和线索是Surface.View及其子类(TextView,Button等)要画在Surface上。每个Surface创建一个Canvas对象(但属性时常改变),用来管理view在Surface上的绘图操作,如画点画线,使用它是,一般都是出现在  最顶层。  (2.)实现  首先继承SurfaceView并实现SurfaceHolder.Callback接口  使用接口的原因:因为使用SurfaceView有一个原则,所有的绘图工作必须得在Surface被创建之后才能开始(Surface可以当作显存的一个映射,写入到Surface的内容,可以被直接复制到显存中从而显示出来,这使得显示的速度会非常快),而在Surface被销毁之前必须结束。所以CallBack中的surfaceCreated和surfaceDestroyed就成了绘图代理代码的边界。  需要重写的方法:  a. public void sufaceChanged(SurfaceHolder holder,int format,int width,int height){}//Surface的大小发生改变时调用  b. public void surfaceCreated(SurfaceHolder holder){}//Surface创建时激发,一般在这里调用画面的线程。  c. public void surfaceDestroyed(SurfaceHolder holder){}//销毁时激发,一般在这里将画面的线程停止、释放。  d. public void addCallback{};//给SurfaceView添加一个回调函数。  e. public void lockCanvas{};//锁定画布。绘图之前必须锁定画布才能够得到画布对象。  f. public void unlockCanvasAndPost{};//开始绘制时锁定了画布,绘制完成后解锁画布。  g. public void removeCallback:从SurfaceView中移除回调函数。  SurfaceView不同View之处在于,SurfaceView不需要通过线程来更新视图,但是再绘制前需要使用locakCanvas锁定画布,并且得到画布,然后再画布上绘制你需要的图像。绘制完成后需要使用lockCanvasAndPost方法来解锁画布。于是才能显示在屏幕上。事件的处理规则和View是一样的。  整个实现过程:  继承SurfaceView并实现SurfaceHolder.Callback接口------&SurfaceView.getHolder()获得SurfaceHolder对象-----&SurfaceHolder.addCallback(callback)添加回调函数-----&  surfaceHolder.lockCanvas()获得Canvas对象并锁定画布------&Canvas绘画-------&SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。  (3.)SurfaceHolder:  这里用到了一个类SurfaceHolder,可以把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。  几个常用的方法:  a.abstract void addCallback(SurfaceHolder.Callbask callback);//给SurfaceView当前的持有者一个回调函数。  b.abstract Canvas lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面等操纵了。  c.abstract Canvas lockCanvas(Rect dirty);//锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost()来改变显示的内容。相对部分内存要求比较高的游戏来说, 可以不用重画dirty外的其他区域的像素,可以提高速度。  d.abstract void unlockCanvasAndPost(Canvas canvas);//结束锁定画图,并提交改变。  最后通过一个SurfaceView开发一个示波器的例子,来结束SurfaceView吧(代码太多,放在下一页中
),谢谢  SurfaceView 示波器的例子:直接上代码了就  该程序会根据单击的按钮在屏幕上自动绘制正弦波和余弦波形。程序每次绘制时只需要绘制(更新)当前点的波形,前面已经绘制的波形无须更新,利用了SurfaceHolder的lockCanvas(Rect r)方法  1.布局文件Layout/show_wave.xml:  package com.infy.  import java.util.T  import java.util.TimerT  import Android.app.A  import android.graphics.C  import android.graphics.C  import android.graphics.P  import android.graphics.R  import android.os.B  import android.view.SurfaceH  import android.view.SurfaceV  import android.view.V  import android.view.SurfaceHolder.C  import android.view.View.OnClickL  import android.widget.B  public class ShowWave extends Activity{  private SurfaceH  private P  final int HEIGHT=320;  final int WIDTH=320;  final int X_OFFSET = 5;  private int cx = X_OFFSET;  //实际的Y轴的位置  int centerY = HEIGHT /2;  Timer timer = new Timer();  TimerTask task =  @Override  protected void onCreate(Bundle savedInstanceState) {  // TODO Auto-generated method stub  super.onCreate(savedInstanceState);  setContentView(R.layout.show_wave);  final SurfaceView surface = (SurfaceView)findViewById(R.id.show);  //初始化SurfaceHolder对象  holder = surface.getHolder();  paint = new Paint();  paint.setColor(Color.GREEN);  paint.setStrokeWidth(3);  Button sin =(Button)findViewById(R.id.sin);  Button cos =(Button)findViewById(R.id.cos);  OnClickListener listener = (new OnClickListener() {  @Override  public void onClick(final View source) {  // TODO Auto-generated method stub  drawBack(holder);  cx = X_OFFSET;  if(task != null){  task.cancel();  }  task = new TimerTask() {  @Override  public void run() {  int cy = source.getId() == R.id.sin ? centerY -(int)(100 * Math.sin((cx -5) *2 * Math.PI/150)):  centerY -(int)(100 * Math.cos((cx-5)*2*Math.PI/150));  Canvas canvas = holder.lockCanvas(new Rect(cx,cy-2,cx+2,cy+2));  canvas.drawPoint(cx, cy, paint);  cx++;  if(cx &WIDTH){  task.cancel();  task =  }  holder.unlockCanvasAndPost(canvas);  }  };  timer.schedule(task, 0,30);  }  });  sin.setOnClickListener(listener);  cos.setOnClickListener(listener);  holder.addCallback(new Callback() {  public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){  drawBack(holder);  }  @Override  public void surfaceCreated(SurfaceHolder holder) {  // TODO Auto-generated method stub  }  @Override  public void surfaceDestroyed(SurfaceHolder holder) {  // TODO Auto-generated method stub  timer.cancel();  }  });  }  private void drawBack(SurfaceHolder holder){  Canvas canvas = holder.lockCanvas();  //绘制白色背景  canvas.drawColor(Color.WHITE);  Paint p = new Paint();  p.setColor(Color.BLACK);  p.setStrokeWidth(2);  //绘制坐标轴  canvas.drawLine(X_OFFSET, centerY, WIDTH, centerY, p);  canvas.drawLine(X_OFFSET, 40, X_OFFSET, HEIGHT, p);  holder.unlockCanvasAndPost(canvas);  holder.lockCanvas(new Rect(0,0,0,0));  holder.unlockCanvasAndPost(canvas);  }  }  3.最后显示结果:
其他类似问题
为您推荐:
提问者采纳
这个是一直在刷新的,你下一次画的时候画透明就行了
其他1条回答
paint.Mode,互相理解。这基本上意味着;然后你可以用它来画什么 shape 你想为了获得 effect 。如果您对我的回答有不满意的地方;答题不易;透明地画&quot.CLEAR)),还请您继续追问.setXfermode(new PorterDuffXfermode(PorterDuff如果您想要清除的一部分 SurfaceView 你可以设置这种模式对画家,&quot,互相帮助;
surfaceview的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁Android中View,SurfaceView的绘图和GLSurfaceView绘图有区别吗_百度知道
Android中View,SurfaceView的绘图和GLSurfaceView绘图有区别吗
我有更好的答案
  如果你的游戏不吃CPU,用View就比较好,符合标准Android操作方式,由系统决定刷新surface的时机。
  但如果很不幸的,你做不到不让你的程序吃CPU,你就只好使用SurfaceView来强制刷新surface了,不然系统的UI进程很可能抢不过你那些吃CPU的线程。
  当然其实不止这两种方法来刷新Surface的,这两种只是纯Java应用比较常见的方法。
  SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。
  那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
  当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线...
其他类似问题
为您推荐:
surfaceview的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁SurfaceView使用介绍 - 博客频道 - CSDN.NET
DavenCheung
微博搜索InfoStation关注
分类:Android开发高级教程
& & & &&转载请注明:http://blog.csdn.net/zhangshuaizaxia/article/details/,来自Davencheung的博客!
什么是SurfaceView?
& & & &&其实在去年学习Android的APIDEMO的时候,有接触到SurfaceView, 但是却一直不是很明白他的作用,只知道他和View有一些区别。事实上,SurfaceView是继承View。我们知道Android系统通过发出VSYNC信号来刷新屏幕,刷新的时间间隔为16ms,也就是在有屏幕刷新的情况下,view的draw函数中的内容必须在16ms内完成,如果超出这个时间,就会出现掉帧。而SurfaceView何时刷新,则是可以控制的。
& & & &&下面是surfaceView的API的译文(摘自网络)
& & &&SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置,surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者
surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和
surfaceDestroyed(SurfaceHolder)。
& & & & surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
& & & & 1. 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
& & & & 2. 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
& & & &&另外,通过下面几点,你可以确定何时选择使用SurfaceView:
& & & &&1. View适用于主动更新的情况下,而SurfaceView适应于被动刷新,频繁的刷新,例如游戏界面;
& & & &&2. View在主线程中对画面进行刷新,而SurfaceView通常会通过一个子线程来进行页面的刷新;(可以在子线程中做大量的处理)
& & & &&3. View在绘图的时候没有使用双缓存的机制,而SurfaceView在底层使用双缓存的机制。
SurfaceView使用模板
& & & &&SurfaceView的使用是有规矩可以遵循,在《Android群英会》一书中,作者给出了一个使用模板,使用起来很简单!
package com.cheungshuai.
import java.util.C
import android.content.C
import android.graphics.C
import android.graphics.C
import android.graphics.P
import android.graphics.Paint.A
import android.graphics.P
import android.util.AttributeS
import android.view.SurfaceH
import android.view.SurfaceV
* @author davencheung
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable{
private SurfaceHolder mH
private Canvas mC
private boolean mIsD//whether is drawing
public SurfaceViewTemplate(Context context) {
super(context);
initView();
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
public SurfaceViewTemplate(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
private void initView(){
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
setKeepScreenOn(true);
//do something here!
mPaint = new Paint();
mPaint.setTextSize(50);
mPaint.setColor(Color.RED);
mPaint.setTextAlign(Align.CENTER);
private Calendar mC
private Paint mP
private String mT
public void run() {
while(mIsDrawing){
private void draw(){
mCanvas = mHolder.lockCanvas();
//do something here!
mCanvas.drawColor(Color.WHITE);
mCalendar = Calendar.getInstance();
mTime = mCalendar.get(Calendar.HOUR_OF_DAY)+&时&+
mCalendar.get(Calendar.MINUTE)+&分&+
mCalendar.get(Calendar.SECOND)+&秒&;
mCanvas.drawText(mTime, getWidth()/2, getHeight()/2, mPaint);
}catch(Exception e){
if(mCanvas != null){
mHolder.unlockCanvasAndPost(mCanvas);
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing =
new Thread(this).start();
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing =
& & & &&基本上按照上面的使用方法,就可以完成很多事情。我们要做的就是在下面这行代码下面添加一些自己的内容即可!
//do something here!
& & & &&而在MainActiivity中只需要如下的处理:
SurfaceViewTemplate sv = new SurfaceViewTemplate(this);
setContentView(sv);
控制刷新间隔时间
& & & &&另外,我们可以在线程的run函数中控制线程的运行,然后是的刷新间隔时间改变。
& & & &&例如,修改下面的代码,就可以让界面每5秒刷新一次!
while(mIsDrawing){
Thread.sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
& & & &&记住,这个sleep需要在while循环调用,因为,第一次运行之后,界面就一直通过这个循环来刷新,不会再走其他的流程,代码无法执行到(Android群英会中的示例应该有问题),直到退出应用!
& & & &&运行的效果图如下:
zhangshuaizaxia
排名:千里之外
(13)(3)(1)(3)(10)(2)(1)(0)(2)(4)(1)(1)(2)(4)(1)(9)(0)Android中View, SurfaceView的绘图和GLSurfaceView绘图有区别吗?
在做一个功能的时候一开始用的View绘图,在有些性能一般的机器上会比较卡,后来使用SurfaceView来绘图,性能提高了很多,但是在非常垃圾的机器上还是会卡。后来本来打算尝试用GLSurfaceView绘图。但是因为OpenGL ES的API不太会用就一直没实现出来,然后就搁置了。但是我有一个疑问,就是,如果我用GLSurfaceView的API封装一套和Canvas一样的接口,绘图上,GLSurfaceView会更加快速么?
按投票排序
View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,openGL专用。在2D游戏开发中,大致可以分为两种游戏框架,View和SurfaceView。 View和SurfaceView区别:View:必须在UI的主线程中更新画面,用于被动更新画面。surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步,涉及到线程同步。所以基于以上,根据游戏特点,一般分成两类。 1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。 2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。
感谢评论中各位大牛的纠正~~个人理解:1)使用canvas/paint方式的绘图为软件渲染,通过cpu实现;使用opengles/shader方式的绘图为硬件加速渲染,通过gpu实现。2)surfaceview和glsurfaceview的显示一般结合opengles,使用纹理(texture),为硬件渲染,通过gpu实现3)glsurfaceview是surfaceview的子类,在后者基础上封装了egl环境管理,以及render线程4)opengles绘制函数及shader是平台无关的,需要egl环境对接android/ios等平台5)android graphic 底层都与BufferQueue、Surfaceflinger等相关,具体可参考android开发者文档个人经验,如有不对之处请帮忙指出
surfaceview是view的子类,GLSurfaceView是surfaceview的子类。毫无疑问子类会比父类功能更强大。但是楼主所问的用GLSurfaceView的API封装一套和Canvas一样的接口,绘图上,GLSurfaceView会更加快速么?那还真不一定。原因在于android系统内部其实对view做了许多优化,比如说 硬件加速。而硬件加速的本质,其实就是将所有的绘制命令 放入一个列表DisplayList,然后用 OpenGL ES的绘制指令 去做最终绘制。所以,你想做的 ,android已经替你做好了。但是有些低端机型上不支持硬件加速,才导致绘制效率低下。这些不支持硬件加速的 机型往往也可能无法完全支持OpenGL ES。
而且换个角度来说,OpenGL的效率之所以高一部分是因为 异步线程进行绘制能获得更平滑的绘制效果;另一部分是因为分层操作,它在你绘制上一幅画面的时候就提前绘制好下一副画面,然后再在显示下一副图片的时候直接交换,不同于像view那样通过刷新脏区域重新绘制。但这就意味着要消耗双倍的内存。 低端机的内存是否足够支撑OpenGL的消耗也是个需要考虑的问题。
另外GLSurfaceView还有一个特点,就是它不支持控件动画。原因在于 OpenGL是一套跨平台的图形库,为了跨平台,它里面不包含任何执行窗口任务或者处理用户输入的函数,我们需要通过应用程序本身所运行的窗口系统来提供相应操作才能处理这些操作,所以OpenGL的绘制相当于是在view上打了一个洞直接绘制在surface上。如果你想要做一个层级比较深的界面,直接用surfaceview会比用OpenGL方便的多。
当然,作为最底层的图形库,OpenGL的性能是毋庸置疑的。像素级的控制,通过着色器能达到很多view 难以达到的效果。具体选择用哪种方式,还是要视情况而定。
我觉得……题主你是指动画吧?view只能在主线程绘制,surfaceview则是可以多线程刷新,而opengl则是更深一层的基于native动画库,做了大量优化和封装。同样的手机上同样的动画,view只能跑4帧的,opengl实现能轻松24帧,这就是差距。当然运行成本和实现成本往往不可兼得就是了
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 surfaceview 透明 的文章

 

随机推荐