安卓通过SurfaceView类实现手写功能(上)

1 SurfaceView类简介 1.1 SurfaceView

SurfaceView类的全称是android.view.SurfaceView,派生自andriod.view.ViewSurfaceView类可以看成是“自带独立SurfaceView”,因此该类具有View的显示和接收输入的功能,还可以通过Surface实现绘制的功能。通过SurfaceView类实现手写功能,实际上就是在其Surface上进行绘制,之后再显示出来。

1.2 SurfaceHolder接口

SurfaceHolder接口是对SurfaceViewSurface的封装。通过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获取SurfaceCanvas;然后通过Canvas进行绘画;最后通知主程序将SurfaceViewSurface上的内容显示到主程序的Surface上,完成绘画和显示,如图1所示。

 

 

 安卓通过SurfaceView类实现手写功能(上) - 阿里云

图1 使用SurfaceView类的流程

2 编程实现

在“Android Studio”中新建一个名为“SurfaceView_Test”的项目。

2.1 设置程序的界面布局

程序主要由一个SurfaceView控件和两个Button控件组成,如图2所示。在“app->res->layout”中,编辑自动生成的“activity_main.xml”布局文件,将自带的TextView控件删除。

安卓通过SurfaceView类实现手写功能(上) - 阿里云 

图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指定了该按键是否位于水平居中的位置。