本节讲解使用SurfaceView组件绘制动画的方法。SurfaceView类作为View类的子类,进行绘图时能够比一般的View组件更快,所以我们在Android游戏、视频等对流畅度和帧速要求较高的应用中经常会见到SurfaceView的身影。

       本文通过实例讲解的方式来介绍SurfaceView的使用方法,此实例实现的是一个能发送莫尔斯码的灯塔。下面是详细步骤,代码中的注释可以帮助大家理解。

       1、创建项目Lesson25_Morse,启动Activity名字叫MainActivity.java。

       2、创建一个莫尔斯码的工具类Morse.java。

Java代码
  1. package basic.android.lesson37;   
  2.   
  3. import java.util.HashMap;   
  4. import java.util.Map;   
  5.   
  6. public class Morse {   
  7.   
  8.     public static Map<STRING string ,> standardMorseCharactersMap = new HashMap</STRING><STRING string ,>();   
  9.   
  10.     static {   
  11.         standardMorseCharactersMap.put("a"".-");   
  12.         standardMorseCharactersMap.put("b""-...");   
  13.         standardMorseCharactersMap.put("c""-.-.");   
  14.         standardMorseCharactersMap.put("d""-..");   
  15.         standardMorseCharactersMap.put("e"".");   
  16.         standardMorseCharactersMap.put("f""..-.");   
  17.         standardMorseCharactersMap.put("g""--.");   
  18.         standardMorseCharactersMap.put("h""....");   
  19.         standardMorseCharactersMap.put("i""..");   
  20.         standardMorseCharactersMap.put("j"".---");   
  21.         standardMorseCharactersMap.put("k""-.-");   
  22.         standardMorseCharactersMap.put("l"".-..");   
  23.         standardMorseCharactersMap.put("m""--");   
  24.         standardMorseCharactersMap.put("n""-.");   
  25.         standardMorseCharactersMap.put("o""---");   
  26.         standardMorseCharactersMap.put("p"".--.");   
  27.         standardMorseCharactersMap.put("q""--.-");   
  28.         standardMorseCharactersMap.put("r"".-.");   
  29.         standardMorseCharactersMap.put("s""...");   
  30.         standardMorseCharactersMap.put("t""-");   
  31.         standardMorseCharactersMap.put("u""..-");   
  32.         standardMorseCharactersMap.put("v""...-");   
  33.         standardMorseCharactersMap.put("w"".--");   
  34.         standardMorseCharactersMap.put("x""-..-");   
  35.         standardMorseCharactersMap.put("y""-.--");   
  36.         standardMorseCharactersMap.put("z""--..");   
  37.   
  38.         standardMorseCharactersMap.put("0""-----");   
  39.         standardMorseCharactersMap.put("1"".----");   
  40.         standardMorseCharactersMap.put("2""..---");   
  41.         standardMorseCharactersMap.put("3""...--");   
  42.         standardMorseCharactersMap.put("4""....-");   
  43.         standardMorseCharactersMap.put("5"".....");   
  44.         standardMorseCharactersMap.put("6""-....");   
  45.         standardMorseCharactersMap.put("7""--...");   
  46.         standardMorseCharactersMap.put("8""---..");   
  47.         standardMorseCharactersMap.put("9""----.");   
  48.   
  49.         standardMorseCharactersMap.put("."".-.-.-");   
  50.         standardMorseCharactersMap.put("-""-....-");   
  51.         standardMorseCharactersMap.put(",""--..--");   
  52.         standardMorseCharactersMap.put("?""..--..");   
  53.         standardMorseCharactersMap.put("/""-..-.");   
  54.         standardMorseCharactersMap.put(";""-.-.-.");   
  55.         standardMorseCharactersMap.put("(""-.--.");   
  56.         standardMorseCharactersMap.put(")""-.--.-");   
  57.         standardMorseCharactersMap.put("@"".--.-.");   
  58.         standardMorseCharactersMap.put("*""...-.-");   
  59.         standardMorseCharactersMap.put("+"".-.-.");   
  60.         standardMorseCharactersMap.put("%"".-...");   
  61.         standardMorseCharactersMap.put("\\", "---...");  
  62.         standardMorseCharactersMap.put("\""".-..-.");   
  63.         standardMorseCharactersMap.put("'"".----.");   
  64.         standardMorseCharactersMap.put("!""=---.");   
  65.         standardMorseCharactersMap.put("$""...-..-");   
  66.         standardMorseCharactersMap.put(" ""/");   
  67.     }   
  68.   
  69.     public static String morseEncoder(String input) {   
  70.         String output = "";   
  71.         for (char c : input.toCharArray()) {   
  72.             output += standardMorseCharactersMap.get(String.valueOf(c)) + " ";   
  73.         }   
  74.         return output;   
  75.     }   
  76.   
  77.     public static void main(String[] args) {   
  78.         String input = "yao mu yang";   
  79.         String output = Morse.morseEncoder(input);   
  80.         System.out.println(output);   
  81.     }   
  82.   
  83. }</STRING>  

       3、布局文件main.xml 的内容如下:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <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">  
  3.   
  4.     <TEXTVIEW android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输入:">  
  5.     </TEXTVIEW>  
  6.   
  7.     <EDITTEXT android:id="@+id/EditText01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="">  
  8.     </EDITTEXT>  
  9.   
  10.     <BUTTON type=submit android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转换">  
  11.     </BUTTON>  
  12.   
  13.     <TEXTVIEW android:id="@+id/TextView02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="输出:">  
  14.     </TEXTVIEW>  
  15.   
  16.     <EDITTEXT android:id="@+id/EditText02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:editable="false">  
  17.     </EDITTEXT>    
  18.   
  19.     <BUTTON type=submit android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送信号">  
  20.     </BUTTON>  
  21. </LINEARLAYOUT>  

       4、MainActivity.java的内容如下:

Java代码
  1. package basic.android.lesson37;   
  2.   
  3. import android.app.Activity;   
  4. import android.content.Context;   
  5. import android.graphics.Canvas;   
  6. import android.graphics.Color;   
  7. import android.graphics.Paint;   
  8. import android.os.Bundle;   
  9. import android.util.Log;   
  10. import android.view.SurfaceHolder;   
  11. import android.view.SurfaceView;   
  12. import android.view.View;   
  13. import android.widget.Button;   
  14. import android.widget.EditText;   
  15. import android.widget.LinearLayout;   
  16.   
  17. public class MainActivity extends Activity {   
  18.      private LinearLayout layout;   
  19.   
  20.      //莫尔斯码数组变量   
  21.       char[] chars;   
  22.      //莫尔斯码数组计数变量   
  23.       int count = 0;   
  24.      //开关标志   
  25.       boolean flag = false;   
  26.      //循环标志   
  27.       boolean loop = false;   
  28.   
  29.      @Override  
  30.      public void onCreate(Bundle savedInstanceState) {   
  31.      super.onCreate(savedInstanceState);   
  32.      setContentView(R.layout.main);   
  33.   
  34.      // 定义UI组件   
  35.      final Button b1 = (Button) findViewById(R.id.Button01);   
  36.      final Button b2 = (Button) findViewById(R.id.Button02);   
  37.   
  38.      final EditText et1 = (EditText) findViewById(R.id.EditText01);   
  39.      final EditText et2 = (EditText) findViewById(R.id.EditText02);   
  40.   
  41.      layout = (LinearLayout) findViewById(R.id.LinearLayout01);   
  42.   
  43.      // 单击转换按钮,转换莫尔斯码   
  44.      b1.setOnClickListener(new View.OnClickListener(){   
  45.   
  46.      @Override  
  47.      public void onClick(View v) {   
  48.          String text = Morse.morseEncoder(et1.getText().toString());   
  49.          et2.setText(text);   
  50.      }   
  51.      });   
  52.   
  53.      // 单击发送信号按钮,把莫尔斯码用灯信号的方式发送出去   
  54.      b2.setOnClickListener(new View.OnClickListener() {   
  55.   
  56.         @Override  
  57.         public void onClick(View v) {   
  58.             //当morse码文本框中有内容的时候就发送灯信号   
  59.             if (et2.getText() != null && et2.getText().toString().length() > 0) {   
  60.                 //把莫尔斯码拆解成一个一个字符   
  61.                 chars = et2.getText().toString().toCharArray();   
  62.                 //计数   
  63.                 count = chars.length;   
  64.                 //创建SurfaceView   
  65.                 LightView light = new LightView(MainActivity.this);   
  66.                 //把SurfaceView动态加入Activity   
  67.                 layout.addView(light);   
  68.             }   
  69.         }   
  70.     });   
  71.     }   
  72.   
  73.     // 信号灯   
  74.     class LightView extends SurfaceView {   
  75.   
  76.        //声明 surfaceHolder 对象   
  77.        SurfaceHolder holder;   
  78.   
  79.        // 构造方法   
  80.        public LightView(Context context) {   
  81.            super(context);   
  82.   
  83.            // 从 SurfaceView 中获取 SurfaceHolder对象   
  84.            holder = this.getHolder();   
  85.            // addCallback 对象   
  86.            holder.addCallback(new SurfaceHolder.Callback() { //创建SurfaceHolder.Callback匿名内部类   
  87.   
  88.               //在SurfaceHolder.Callback内部类的内部创建它所需要的线程内部类   
  89.               class LightThread implements Runnable {   
  90.   
  91.                   @Override  
  92.                   public void run() {   
  93.   
  94.                      while (loop) {   
  95.   
  96.                         if (count > 0) {   
  97.                             Log.i("yao""" + count);   
  98.                             String s = String.valueOf(chars[chars.length - count]);   
  99.                             // 锁定canvas,开始绘图   
  100.                             Canvas canvas = holder.lockCanvas(null);   
  101.   
  102.                             Paint paint = new Paint();   
  103.                             paint.setAntiAlias(true);   
  104.   
  105.                             //清屏幕   
  106.                             paint.setColor(Color.BLACK);   
  107.                             canvas.drawRect(00480480, paint);                                                            
  108.   
  109.                             //标志位是真的时候关一下灯   
  110.                             if(flag){   
  111.                                 sleep(2);   
  112.                                 paint.setColor(Color.BLACK);   
  113.                             }else//为假的时候就亮灯   
  114.                                 // di 亮2个时间点   
  115.                                 if (s.equalsIgnoreCase(".")) {   
  116.                                     sleep(2);   
  117.                                     paint.setColor(Color.YELLOW);   
  118.                                 } else if(s.equalsIgnoreCase("-")) {   
  119.                                     // dah 亮4个时间点   
  120.                                     sleep(4);   
  121.                                     paint.setColor(Color.YELLOW);   
  122.                                 }else if(s.equalsIgnoreCase(" ")){   
  123.                                     // 空格 亮2个时间点   
  124.                                     sleep(2);   
  125.                                     paint.setColor(Color.BLACK);   
  126.                                 }else if(s.equalsIgnoreCase("/")){   
  127.                                     // 单词之间的空白亮2个时间点   
  128.                                     sleep(2);   
  129.                                     paint.setColor(Color.BLACK);   
  130.                                 }else{   
  131.                                     // 出问题的时候亮红灯   
  132.                                     sleep(2);   
  133.                                     paint.setColor(Color.RED);   
  134.                                 }   
  135.                                 count--;   
  136.                             }   
  137.                             //绘制灯光   
  138.                             canvas.drawCircle(250.0f, 200.0f, 100, paint);   
  139.   
  140.                             //标准位开关   
  141.                             flag = !flag;      
  142.   
  143.                             // 释放canvas,绘图完毕   
  144.                             holder.unlockCanvasAndPost(canvas);   
  145.                         }   
  146.   
  147.                      }   
  148.   
  149.                   }   
  150.   
  151.                   //休眠   
  152.                   public void sleep(int time){   
  153.                      try {   
  154.                          Thread.sleep(time*80);   
  155.                      } catch (Exception e) {   
  156.                         //no nothing   
  157.                      }   
  158.                  }   
  159.               }   
  160.   
  161.               @Override  
  162.               public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {   
  163.                 // do nothing   
  164.               }   
  165.   
  166.               @Override  
  167.               public void surfaceCreated(SurfaceHolder holder) {   
  168.                  //在SurfaceView被创建的时候执行   
  169.                  new Thread(new LightThread()).start();   
  170.               }   
  171.   
  172.               @Override  
  173.               public void surfaceDestroyed(SurfaceHolder holder) {   
  174.                  loop = false;   
  175.               }   
  176.           });   
  177.   
  178.           loop = true;   
  179.   
  180.         }   
  181.     }  
  182. }  

       5、编译并运行程序,查看结果:

SurfaceView实现的莫尔斯灯塔

       好了,本讲就到这里,下次再见。

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/course/180.html
2012年8月30日
发布:鸡啄米 分类:Android开发教程 浏览: 评论:0