Android动画入门

来源:互联网 发布:2016chinajoy数据 编辑:程序博客网 时间:2024/06/08 03:55

 

本讲内容:Android中的绘画动画 SurfaceView
SurfaceView是View的一个子类,它提供了一种比普通View组件绘制速度更快的绘图方式,在游戏、视频等要求高帧速和高流畅度的场合,使用SurfaceView成了一种很好的选择。本讲让我们通过一个能发送莫尔斯码的灯塔实例来讲解SurfaceView的使用,请留意代码中的注释。
一、实例:窈窈莫尔斯灯塔
1、创建项目 Lesson25_Morse , 启动Activity名字叫 MainActivity.java
2、创建一个莫尔斯码的工具类 Morse.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;  @Overridepublic 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() {   @Overridepublic void onClick(View v) { String text = Morse.morseEncoder(et1.getText().toString());et2.setText(text);} });   // 单击发送信号按钮,把莫尔斯码用灯信号的方式发送出去b2.setOnClickListener(newView.OnClickListener() {   @Overridepublic void onClick(View v) { //当morse码文本框中有内容的时候就发送灯信号if (et2.getText() != null && et2.getText().toString().length() > 0) {//把莫尔斯码拆解成一个一个字符chars = et2.getText().toString().toCharArray();//计数 count = chars.length;//创建SurfaceViewLightView light =new LightView(MainActivity.this);//把SurfaceView动态加入Activitylayout.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 {   @Overridepublic 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} } }   @Overridepublicvoid surfaceChanged(SurfaceHolder holder,int format, int width, intheight) { // do nothing}   @Overridepublicvoid surfaceCreated(SurfaceHolder holder) {//在SurfaceView被创建的时候执行new Thread(new LightThread()).start();}   @Overridepublicvoid 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的内容如下:
 
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;  @Overridepublic 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() {   @Overridepublic void onClick(View v) { String text = Morse.morseEncoder(et1.getText().toString());et2.setText(text);} });   // 单击发送信号按钮,把莫尔斯码用灯信号的方式发送出去b2.setOnClickListener(newView.OnClickListener() {   @Overridepublic void onClick(View v) { //当morse码文本框中有内容的时候就发送灯信号if (et2.getText() != null && et2.getText().toString().length() > 0) {//把莫尔斯码拆解成一个一个字符chars = et2.getText().toString().toCharArray();//计数 count = chars.length;//创建SurfaceViewLightView light =new LightView(MainActivity.this);//把SurfaceView动态加入Activitylayout.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 {   @Overridepublic 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} } } @Overridepublicvoid surfaceChanged(SurfaceHolder holder,int format, int width, intheight) { // do nothing}   @Overridepublicvoid surfaceCreated(SurfaceHolder holder) {//在SurfaceView被创建的时候执行new Thread(new LightThread()).start();}   @Overridepublicvoid surfaceDestroyed(SurfaceHolder holder) {loop = false; } });   loop = true;   } } }

 
5、编译并运行程序,查看结果:
1.png
2012-6-25 16:47 上传
下载附件(126.42 KB)