android中Surface View的用法

来源:互联网 发布:2016网络效应试题答案 编辑:程序博客网 时间:2024/06/06 12:44

SurfaceView与普通的View的区别就是View视图必须在当前UI线程中进行,这也是在更新View组件时总要采用Handler处理的原因;但SurfeceView不会存在这个问题,它的绘图是由SurfaceHolder来完成的,SurfaceHolder会启动新的线程去更新SurfaceView的绘制,不会阻塞主UI线程。一般而言,如果程序中或游戏界面中的动画元素较多,而且很多动画元素都需要通过定时器来控制,就可以考虑使用SurfaceView而不是View。

使用SurfaceView时,需要在新建线程去更新UI。其使用步骤如下:

1.用findViewById获取SurfaceView实例

2.用其getHolder方法取得holder实例

3.利用holder的holder.lockCanvas()封锁并获取Canvas实例

4.在Canvas上绘制相应图形

5.用holder.unlockCanvasAndPost(canvas)方法解锁并将Canvas显示到SurfaceView上面


下面是一个绘制正弦余弦的实例(不断地获取x所对应的正弦余弦的y值并将其绘制出来)

maiin.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="match_parent"   android:layout_height="match_parent"><LinearLayout android:orientation="horizontal"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:gravity="center"   ><Button android:id="@+id/sin"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:text="@string/sin"   /><Button android:id="@+id/cos"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:text="@string/cos"   /> </LinearLayout><SurfaceView android:id="@+id/show"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:gravity="center"   /></LinearLayout>

MainActivity.java
package com.example.wanglunhui.showware;import android.app.Activity;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button;import java.util.Timer;import java.util.TimerTask;public class MainActivity extends Activity{    private SurfaceHolder holder;    private Paint paint;    final int HEIGHT = 320;    final int WIDTH = 768;    final int X_OFFSET = 5;    private int cx = X_OFFSET;    // 实际的Y轴的位置    int centerY = HEIGHT / 2;    Timer timer = new Timer();    TimerTask task = null;    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        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);        View.OnClickListener listener = (new View.OnClickListener()        {            @Override            public void onClick(final View source)            {                drawBack(holder);                cx = X_OFFSET;                if(task != null)                {                    task.cancel();                }                task = new TimerTask()                {                    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 = null;                        }                        holder.unlockCanvasAndPost(canvas);                    }                };                timer.schedule(task , 0 , 30);            }        });        sin.setOnClickListener(listener);        cos.setOnClickListener(listener);        holder.addCallback(new SurfaceHolder.Callback()        {            @Override            public void surfaceChanged(SurfaceHolder holder, int format,                                       int width, int height)            {                drawBack(holder);            }            @Override            public void surfaceCreated(final SurfaceHolder myHolder){ }            @Override            public void surfaceDestroyed(SurfaceHolder holder)            {                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);    }}

0 0