本节讲解使用SurfaceView组件绘制动画的方法。SurfaceView类作为View类的子类,进行绘图时能够比一般的View组件更快,所以我们在Android游戏、视频等对流畅度和帧速要求较高的应用中经常会见到SurfaceView的身影。
本文通过实例讲解的方式来介绍SurfaceView的使用方法,此实例实现的是一个能发送莫尔斯码的灯塔。下面是详细步骤,代码中的注释可以帮助大家理解。
1、创建项目Lesson25_Morse,启动Activity名字叫MainActivity.java。
2、创建一个莫尔斯码的工具类Morse.java。
- package basic.android.lesson37;
- import java.util.HashMap;
- import java.util.Map;
- public class Morse {
- public static Map<STRING string ,> standardMorseCharactersMap = new HashMap</STRING><STRING string ,>();
- static {
- standardMorseCharactersMap.put("a", ".-");
- standardMorseCharactersMap.put("b", "-...");
- standardMorseCharactersMap.put("c", "-.-.");
- standardMorseCharactersMap.put("d", "-..");
- standardMorseCharactersMap.put("e", ".");
- standardMorseCharactersMap.put("f", "..-.");
- standardMorseCharactersMap.put("g", "--.");
- standardMorseCharactersMap.put("h", "....");
- standardMorseCharactersMap.put("i", "..");
- standardMorseCharactersMap.put("j", ".---");
- standardMorseCharactersMap.put("k", "-.-");
- standardMorseCharactersMap.put("l", ".-..");
- standardMorseCharactersMap.put("m", "--");
- standardMorseCharactersMap.put("n", "-.");
- standardMorseCharactersMap.put("o", "---");
- standardMorseCharactersMap.put("p", ".--.");
- standardMorseCharactersMap.put("q", "--.-");
- standardMorseCharactersMap.put("r", ".-.");
- standardMorseCharactersMap.put("s", "...");
- standardMorseCharactersMap.put("t", "-");
- standardMorseCharactersMap.put("u", "..-");
- standardMorseCharactersMap.put("v", "...-");
- standardMorseCharactersMap.put("w", ".--");
- standardMorseCharactersMap.put("x", "-..-");
- standardMorseCharactersMap.put("y", "-.--");
- standardMorseCharactersMap.put("z", "--..");
- standardMorseCharactersMap.put("0", "-----");
- standardMorseCharactersMap.put("1", ".----");
- standardMorseCharactersMap.put("2", "..---");
- standardMorseCharactersMap.put("3", "...--");
- standardMorseCharactersMap.put("4", "....-");
- standardMorseCharactersMap.put("5", ".....");
- standardMorseCharactersMap.put("6", "-....");
- standardMorseCharactersMap.put("7", "--...");
- standardMorseCharactersMap.put("8", "---..");
- standardMorseCharactersMap.put("9", "----.");
- standardMorseCharactersMap.put(".", ".-.-.-");
- standardMorseCharactersMap.put("-", "-....-");
- standardMorseCharactersMap.put(",", "--..--");
- standardMorseCharactersMap.put("?", "..--..");
- standardMorseCharactersMap.put("/", "-..-.");
- standardMorseCharactersMap.put(";", "-.-.-.");
- standardMorseCharactersMap.put("(", "-.--.");
- standardMorseCharactersMap.put(")", "-.--.-");
- standardMorseCharactersMap.put("@", ".--.-.");
- standardMorseCharactersMap.put("*", "...-.-");
- standardMorseCharactersMap.put("+", ".-.-.");
- standardMorseCharactersMap.put("%", ".-...");
- standardMorseCharactersMap.put("\\", "---...");
- standardMorseCharactersMap.put("\"", ".-..-.");
- standardMorseCharactersMap.put("'", ".----.");
- standardMorseCharactersMap.put("!", "=---.");
- standardMorseCharactersMap.put("$", "...-..-");
- standardMorseCharactersMap.put(" ", "/");
- }
- public static String morseEncoder(String input) {
- String output = "";
- for (char c : input.toCharArray()) {
- output += standardMorseCharactersMap.get(String.valueOf(c)) + " ";
- }
- return output;
- }
- public static void main(String[] args) {
- String input = "yao mu yang";
- String output = Morse.morseEncoder(input);
- System.out.println(output);
- }
- }</STRING>
3、布局文件main.xml 的内容如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LINEARLAYOUT xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLayout01" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
- <TEXTVIEW android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输入:">
- </TEXTVIEW>
- <EDITTEXT android:id="@+id/EditText01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="">
- </EDITTEXT>
- <BUTTON type=submit android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转换">
- </BUTTON>
- <TEXTVIEW android:id="@+id/TextView02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输出:">
- </TEXTVIEW>
- <EDITTEXT android:id="@+id/EditText02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:editable="false">
- </EDITTEXT>
- <BUTTON type=submit android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送信号">
- </BUTTON>
- </LINEARLAYOUT>
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 extends Activity {
- private LinearLayout layout;
- //莫尔斯码数组变量
- char[] chars;
- //莫尔斯码数组计数变量
- int count = 0;
- //开关标志
- boolean flag = false;
- //循环标志
- boolean loop = 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(new View.OnClickListener(){
- @Override
- public void onClick(View v) {
- String text = Morse.morseEncoder(et1.getText().toString());
- et2.setText(text);
- }
- });
- // 单击发送信号按钮,把莫尔斯码用灯信号的方式发送出去
- b2.setOnClickListener(new View.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(new SurfaceHolder.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);
- } else if(s.equalsIgnoreCase("-")) {
- // dah 亮4个时间点
- sleep(4);
- paint.setColor(Color.YELLOW);
- }else if(s.equalsIgnoreCase(" ")){
- // 空格 亮2个时间点
- sleep(2);
- paint.setColor(Color.BLACK);
- }else if(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);
- }
- }
- }
- //休眠
- public void sleep(int time){
- try {
- Thread.sleep(time*80);
- } catch (Exception e) {
- //no nothing
- }
- }
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // do nothing
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- //在SurfaceView被创建的时候执行
- new Thread(new LightThread()).start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- loop = false;
- }
- });
- loop = true;
- }
- }
- }
5、编译并运行程序,查看结果:
好了,本讲就到这里,下次再见。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。