本讲内容:Android中的绘画动画 SurfaceView
SurfaceView是View的一个子类,它提供了一种比普通View组件绘制速度更快的绘图方式,在游戏、视频等要求高帧速和高流畅度的场合,使用SurfaceView成了一种很好的选择。本讲让我们通过一个能发送莫尔斯码的灯塔实例来讲解SurfaceView的使用,请留意代码中的注释。
一、实例:窈窈莫尔斯灯塔
1、创建项目 Lesson25_Morse , 启动Activity名字叫 MainActivity.java
2、创建一个莫尔斯码的工具类 Morse.java
3、布局文件 main.xml 的内容如下:
4、MainActivity.java的内容如下:
package basic.android.lesson37;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
public class MainActivity extendsActivity {
privateLinearLayout layout;
//莫尔斯码数组变量
char[] chars;
//莫尔斯码数组计数变量
int count = 0;
//开关标志
booleanflag = false;
//循环标志
booleanloop = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 定义UI组件
final Button b1 = (Button) findViewById(R.id.Button01);
final Button b2 = (Button) findViewById(R.id.Button02);
final EditText et1 = (EditText) findViewById(R.id.EditText01);
final EditText et2 = (EditText) findViewById(R.id.EditText02);
layout = (LinearLayout) findViewById(R.id.LinearLayout01);
// 单击转换按钮,转换莫尔斯码
b1.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(View v) {
String text = Morse.morseEncoder(et1.getText().toString());
et2.setText(text);
}
});
// 单击发送信号按钮,把莫尔斯码用灯信号的方式发送出去
b2.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(View v) {
//当morse码文本框中有内容的时候就发送灯信号
if (et2.getText() != null && et2.getText().toString().length() > 0) {
//把莫尔斯码拆解成一个一个字符
chars = et2.getText().toString().toCharArray();
//计数
count = chars.length;
//创建SurfaceView
LightView light =new LightView(MainActivity.this);
//把SurfaceView动态加入Activity
layout.addView(light);
}
}
});
}
// 信号灯
class LightView extends SurfaceView {
//声明 surfaceHolder 对象
SurfaceHolder holder;
// 构造方法
public LightView(Context context) {
super(context);
// 从 SurfaceView 中获取 SurfaceHolder对象
holder = this.getHolder();
// addCallback 对象
holder.addCallback(newSurfaceHolder.Callback() { //创建SurfaceHolder.Callback匿名内部类
//在SurfaceHolder.Callback内部类的内部创建它所需要的线程内部类
class LightThread implements Runnable {
@Override
public void run() {
while (loop) {
if (count > 0) {
Log.i("yao","" + count);
String s = String.valueOf(chars[chars.length - count]);
// 锁定canvas,开始绘图
Canvas canvas = holder.lockCanvas(null);
Paint paint = new Paint();
paint.setAntiAlias(true);
//清屏幕
paint.setColor(Color.BLACK);
canvas.drawRect(0,0, 480,480, paint);
//标志位是真的时候关一下灯
if(flag){
sleep(2);
paint.setColor(Color.BLACK);
}else{//为假的时候就亮灯
// di 亮2个时间点
if (s.equalsIgnoreCase(".")) {
sleep(2);
paint.setColor(Color.YELLOW);
} elseif(s.equalsIgnoreCase("-")) {
// dah 亮4个时间点
sleep(4);
paint.setColor(Color.YELLOW);
}elseif(s.equalsIgnoreCase(" ")){
// 空格 亮2个时间点
sleep(2);
paint.setColor(Color.BLACK);
}elseif(s.equalsIgnoreCase("/")){
// 单词之间的空白亮2个时间点
sleep(2);
paint.setColor(Color.BLACK);
}else{
// 出问题的时候亮红灯
sleep(2);
paint.setColor(Color.RED);
}
count--;
}
//绘制灯光
canvas.drawCircle(250.0f,200.0f, 100, paint);
//标准位开关
flag = !flag;
// 释放canvas,绘图完毕
holder.unlockCanvasAndPost(canvas);
}
}
}
//休眠
publicvoid sleep(inttime){
try {
Thread.sleep(time*80);
} catch(Exception e) {
//no nothing
}
}
}
@Override
publicvoid surfaceChanged(SurfaceHolder holder,int format, int width, intheight) {
// do nothing
}
@Override
publicvoid surfaceCreated(SurfaceHolder holder) {
//在SurfaceView被创建的时候执行
new Thread(new LightThread()).start();
}
@Override
publicvoid surfaceDestroyed(SurfaceHolder holder) {
loop = false;
}
});
loop = true;
}
}
}
3、布局文件 main.xml 的内容如下:
<?xml version="1.0"encoding="utf-8"?>
<linearlayout android:layout_height="fill_parent"android:layout_width="fill_parent"android:orientation="vertical"xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/LinearLayout01">
<textview android:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/TextView01"android:text="输入:">
</textview>
<edittext android:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/EditText01"android:text="">
</edittext>
<button android:layout_height="wrap_content"android:layout_width="wrap_content"android:id="@+id/Button01"android:text="转换">
</button>
<textview android:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/TextView02"android:text="输出:">
</textview>
<edittext android:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/EditText02"android:text="" android:editable="false">
</edittext>
<button android:layout_height="wrap_content"android:layout_width="wrap_content"android:id="@+id/Button02"android:text="发送信号">
</button>
</linearlayout>
4、MainActivity.java的内容如下: