1 SurfaceView类简介
1.1 SurfaceView类
SurfaceView类的全称是android.view.SurfaceView,派生自andriod.view.View。SurfaceView类可以看成是“自带独立Surface的View”,因此该类具有View的显示和接收输入的功能,还可以通过Surface实现绘制的功能。通过SurfaceView类实现手写功能,实际上就是在其Surface上进行绘制,之后再显示出来。
1.2 SurfaceHolder接口
SurfaceHolder接口是对SurfaceView的Surface的封装。通过SurfaceHolder实现对Surface的操作,如改变Surface的大小和格式,编辑Surface上的像素以及监听Surface的改变等。
1.3 SurfaceHolder.Callback接口
该接口用来接收Surface改变的信息。该接口中包含了三个方法,分别是surfaceCreated()、surfaceChanged()和surfaceDestroyed()。当Surface在创建、改变和销毁时,会分别调用上述三个方法。在使用SurfaceHolder来操作Surface时,必须为SurfaceHolder添加回调函数,即重写这三个方法。
1.4 SurfaceView类的使用
在“1.2 SurfaceHolder接口”中以及提到,对SurfaceView的操作实际上是通过SurfaceHolder来实现的。因此,首先通过SurfaceView获取其对应的SurfaceHolder;接下来添加该SurfaceHolder的回调接口,即重写SurfaceHolder.Callback接口的三个成员函数;之后通过SurfaceHolder获取Surface的Canvas;然后通过Canvas进行绘画;最后通知主程序将SurfaceView的Surface上的内容显示到主程序的Surface上,完成绘画和显示,如图1所示。
图1 使用SurfaceView类的流程
2 编程实现
在“Android Studio”中新建一个名为“SurfaceView_Test”的项目。
2.1 设置程序的界面布局
程序主要由一个SurfaceView控件和两个Button控件组成,如图2所示。在“app->res->layout”中,编辑自动生成的“activity_main.xml”布局文件,将自带的TextView控件删除。
图2 程序运行界面
2.1.1 添加SurfaceView控件
在“activity_main.xml”布局文件中添加SurfaceView控件,代码如下所示
<SurfaceView
android:id="@+id/surfVDraw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="50dp" />
其中layout_alignParentBottom控制该控件是否与布局容器底部对齐;layout_alignParentLeft控制该控件是否与布局容器左端对齐;layout_alignParentRight控制该控件是否与布局容器右端对齐;layout_alignParentTop控制该控件是否与布局容器顶端对齐;将以上四个属性值均设置为“true”,表示添加的SurfaceView控件充满了整个容器。layout_marginBottom设置了SurfaceView控件底部的空出来的高度,空出来空间用来放置两个Button控件。
2.1.2 添加Button控件
首先添加“保存”按键控件。
<Button
android:id="@+id/btnSend"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/surfVDraw"
android:layout_alignParentBottom="true"
android:text="保存" />
其中,layout_alignLeft指定了该按键控件与给出ID控件的左侧对齐。
接下来添加“取消”按键控件。
<Button
android:id="@+id/btnCancle"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:text="取消" />
其中,layout_centerHorizontal指定了该按键是否位于水平居中的位置。