Android的SurfaceView使用
2011-08-04 15:49
246 查看
Android的大多数控件都是继承自View的,因此在自定义控件时一般也是继承View类,但是对于高效的,游戏级别的绘图,或者是播放器等要求比较高的地方,普通的View类就
有点吃不开了,这个时候就要用到SurfaceView类。
因为比较高级,所以就该装B,单纯一个继承自SurfaceView类是不行的,必须实现一个SurfaceHolder.Callback接口来指明SurfaceView创建、改变、删除时的回调方法,并且
在SurfaceView中通过一个SurfaceHolder对象来控制SurfaceView。
如果将该SurfaceView作为某个Activity的全屏View,则直接调用setContentView(new MyView());就好了;但若是作为屏幕View的一部份,就应该修改对应的layout XML文件
了,添加类似的布局代码:
<com.android.sv.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);将绘制内容进行呈现
下面是个例子运行图:
主界面:
MyTest界面:
main.xml文件:
有点吃不开了,这个时候就要用到SurfaceView类。
因为比较高级,所以就该装B,单纯一个继承自SurfaceView类是不行的,必须实现一个SurfaceHolder.Callback接口来指明SurfaceView创建、改变、删除时的回调方法,并且
在SurfaceView中通过一个SurfaceHolder对象来控制SurfaceView。
如果将该SurfaceView作为某个Activity的全屏View,则直接调用setContentView(new MyView());就好了;但若是作为屏幕View的一部份,就应该修改对应的layout XML文件
了,添加类似的布局代码:
<com.android.sv.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);将绘制内容进行呈现
下面是个例子运行图:
主界面:
public class MainActivity extends Activity { /** Called when the activity is first created. */ private MyView mSV=null; private Button mBtnOk; private Button mBtnCancle; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mSV=(MyView)findViewById(R.id.sv); mSV.setTag(true); mBtnOk=(Button)findViewById(R.id.btnok); mBtnOk.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub mSV.setTag(true); } }); mBtnCancle=(Button)findViewById(R.id.btnCancel); mBtnCancle.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // TODO Auto-generated method stub mSV.setTag(false); } }); } }
MyTest界面:
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 attrs) { super(context, attrs); holder=getHolder(); holder.addCallback(this); } public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub new Thread(new MyLoop()).start();//在 View 中系统不允许主线程外的线程控制 UI .但是 SurfaceView 却可以 } public void surfaceDestroyed(SurfaceHolder arg0) { // 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); int a=xs.size(); 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){ String a=this.getTag().toString(); if(a.equals("true")){ xs.add(event.getX()); ys.add(event.getY()); } } return true; } class MyLoop implements Runnable{ //熟悉游戏编程的应该很面熟吧,主循环 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.xml文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.android.sv.MyView android:id="@+id/sv" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <Button android:id="@+id/btnok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启绘图"/> <Button android:id="@+id/btnCancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/btnok" android:text="取消绘图"/> </RelativeLayout>
相关文章推荐
- Android中SurfaceView的使用详解
- [学习笔记]用户界面优化之Android SurfaceView的使用
- android进阶-surfaceView的分析和使用
- Android菜鸟的成长笔记(27)——SurfaceView的使用
- Android SurfaceView的使用
- 从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- [Android] SurfaceView使用实例(正余弦移动)
- Android提高第二篇之SurfaceView的基本使用
- android 使用双缓冲辨析及surfaceview使用例程-转载(觉得写的很清楚)
- Android中SurfaceView的使用详解
- [Android]视频浮层效果使用SurfaceView无法正常显示的问题排查和解决方案
- Android之SurfaceView使用
- Android使用SurfaceView画图
- Android中SurfaceView的使用详解及如何在jni(hal层)直接显示
- 【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!
- Android提高21篇之二:SurfaceView的基本使用方法
- Android使用SurfaceView代替AnimationDrawable播放多图帧动画,避免OOM和卡顿
- Android游戏开发14:SurfaceView中使用Tween Animation渐变动画
- 【android 使用两个surfaceview 在摄像机画面上绘图】
- Android使用SurfaceView实现飘赞动画