实习第八天:SurfaceView显示动画效果(1)

来源:互联网 发布:淘宝app看价格曲线 编辑:程序博客网 时间:2024/05/29 12:12

原文地址:http://blog.csdn.net/ypist/article/details/8571032


一、基础知识:

SurfaceView继承自View,View负责在主线程中更新动画,而SurfaceView是在一个新线程中更新动画。

SurfaceView类的主要方法:
// 在SurfaceView创建时调用
pubilic abstract void surfaceCreated(SurfaceHolder holder)
// 在SurfaceView改变时调用
pubilic abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
// 在SurfaceView销毁时调用
pubilic abstract void surfaceDestroyed(SurfaceHolder holder)
// 绘制SurfaceView画面
protected void onDraw(Canvas canvas)
(参数canvas是该SurfaceView的画笔,每一次SurfaceView中画面改变都是调用了该方法)


二、实现效果:

首先有一副图片从屏幕的左下角开始向右上方运动,当图片上沿与手机屏幕上沿相撞时,图片的水平速度大小与方向均不变,竖直方向上速度大小不变,
方向相反;当下沿相撞后,同样效果,直到图片飞出屏幕。之后,屏幕渐渐地显示一幅图片。


三、编程实现:

1. 界面编辑(res\layout\main.xml):

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:layout_width="fill_parent"   
  9.     android:layout_height="wrap_content"   
  10.     android:text="@string/hello"  
  11.     />  
  12. </LinearLayout>  


2. 代码编辑:

(\src\wyf\zcl\MyActivity.Java)

[java] view plain copy
  1. package wyf.zcl;  
  2. /* 
  3.  *  该例子演示surfaceView中简单场景的绘制 
  4.  *  MyActivity.java     为程序的主Activity 
  5.  *  MySurfaceView.java  为程序的SurfaceView类 
  6.  *  Constant.java       常量类,将常量全部写在该类中 
  7.  *  OnDrawThread.java   该类的作用是时时刷新onDraw,进行画面的重绘 
  8.  *  PicRunThread.java   该类是控制duke图片运动的类 
  9.  * */  
  10. import android.app.Activity;                        //引入相关包  
  11. import android.content.pm.ActivityInfo;             //引入相关包  
  12. import android.os.Bundle;                           //引入相关包  
  13. import android.view.Window;                         //引入相关包  
  14. import android.view.WindowManager;                  //引入相关包   
  15. public class MyActivity extends Activity {  
  16.     /** Called when the activity is first created. */  
  17.     private MySurfaceView msv;          //得到surfaceView的引用  
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {   //Activity的生命周期函数,该函数是在程序创建时调用  
  20.         super.onCreate(savedInstanceState);  
  21.         msv=new MySurfaceView(MyActivity.this);         //实例化MySurfaceView的对象  
  22.         requestWindowFeature(Window.FEATURE_NO_TITLE);  //设置屏幕显示没有title栏   
  23.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,    
  24.                       WindowManager.LayoutParams.FLAG_FULLSCREEN);  //设置全屏  
  25.         //设置只允许横屏  
  26.         this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
  27.         setContentView(msv);                            //设置Activity显示的内容为msv  
  28.     }  
  29. }  

(\src\wyf\zcl\Constant.java)

[java] view plain copy
  1. package wyf.zcl;  
  2. import android.view.Display;  
  3. //Constant.java     常量类,将常量全部写在该类中  
  4. public class Constant {  
  5.     public static int SCREENWIDTH=480;  //屏幕宽(本程序为横屏)  
  6.     public static int SCREENHEIGHT=320;     //屏幕高  
  7.     public static int PICWIDTH=64;          //图片宽度  
  8.     public static int PICHEIGHT=64;         //图片高度  
  9.     public static int ONDRAWSPEED=30;       //onDraw线程类的绘制间隔时间  
  10.     public static float PICXSPEED=1.5f;     //图片水平移动速度  
  11.     public static float PICYSPEED=2;        //图片垂直移动速度  
  12.     public static int PICRUNSPEED=30;       //图片的运动线程的刷新速度  
  13.     public static int PICALPHASPEED=20//图片渐暗效果演示刷新速度  
  14. }  

(\src\wyf\zcl\MySurfaceView.java)

[java] view plain copy
  1. package wyf.zcl;  
  2. import android.content.Context;                 //引入相关包  
  3. import android.graphics.Bitmap;                 //引入相关包  
  4. import android.graphics.BitmapFactory;          //引入相关包  
  5. import android.graphics.Canvas;                 //引入相关包  
  6. import android.graphics.Color;                  //引入相关包  
  7. import android.graphics.Paint;                  //引入相关包  
  8. import android.view.Display;                    //引入相关包  
  9. import android.view.SurfaceHolder;              //引入相关包  
  10. import android.view.SurfaceView;                //引入相关包  
  11. public class MySurfaceView extends SurfaceView  
  12. implements SurfaceHolder.Callback{            
  13.     //此处实现SurfaceHolder.Callback接口,为surfaceView添加生命周期回调函数  
  14.     int dy=Display.DEFAULT_DISPLAY;  
  15.     MyActivity ma;                          //得到MyActivity的引用  
  16.     Paint paint;                            //画笔的引用  
  17.     OnDrawThread odt;                       //OnDrawThread类引用  
  18.     PicRunThread prt;                       //图片运动的Thread类引用  
  19.     private float picX=0;                       //图片x坐标  
  20.     private float picY=0;                       //图片y坐标  
  21.     boolean picAlphaFlag=false;                 //图片变暗效果的标记,false为不显示,true为显示。  
  22.     int picAlphaNum=0;                          //图片变暗效果中画笔的alpha值  
  23.     public MySurfaceView(Context context) {  
  24.         super(context);  
  25.         this.ma=(MyActivity) context;             
  26.         //将ma的引用指向调用了该Surfaceview类构造器方法的对象,本例为MyActivity  
  27.         this.getHolder().addCallback(this);     //注册回调接口  
  28.         paint=new Paint();                      //实例化画笔  
  29.         odt=new OnDrawThread(this);             //实例化OnDrawThread类  
  30.         prt=new PicRunThread(this);             //实例化PicRunThread类  
  31.         prt.start();  
  32.     }  
  33.     public void setPicX(float picX) {           //图片x坐标的设置器  
  34.         this.picX = picX;  
  35.     }  
  36.     public void setPicY(float picY) {           //图片y坐标的设置器  
  37.         this.picY = picY;  
  38.     }  
  39.     public void setPicAlphaNum(int picAlphaNum) {//图片变暗效果alpha参数设置器  
  40.         this.picAlphaNum = picAlphaNum;  
  41.     }  
  42.     @Override  
  43.     protected void onDraw(Canvas canvas) {  //onDraw方法,此方法用于绘制图像,图形等  
  44.         super.onDraw(canvas);  
  45.         paint.setColor(Color.WHITE);        //设置画笔为白色  
  46.         canvas.drawRect(00, Constant.SCREENWIDTH, Constant.SCREENHEIGHT, paint);  
  47.         //此处画了一个白色的全屏幕的矩形,目的是设置背景为白色,同时每次重绘时清除背景  
  48.         //进行平面贴图  
  49.         Bitmap bitmapDuke=BitmapFactory.decodeResource(ma.getResources(), R.drawable.duke);  
  50.         canvas.drawBitmap(bitmapDuke, picX, picY, paint);  
  51.         //图片渐暗效果  
  52.         if(picAlphaFlag){  
  53.             Bitmap bitmapBG=BitmapFactory.decodeResource(ma.getResources(), R.drawable.jpg1);  
  54.             paint.setAlpha(picAlphaNum);  
  55.             canvas.drawBitmap(bitmapBG, 0,0, paint);  
  56.         }  
  57.     }  
  58.     @Override  
  59.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  60.             int height) {           //此方法为当surfaceView改变时调用,如屏幕大小改变。  
  61.     }  
  62.     @Override  
  63.     public void surfaceCreated(SurfaceHolder holder) {//此方法为在surfaceView创建时调用  
  64.         odt.start();                //启动onDraw的绘制线程  
  65.     }  
  66.     @Override  
  67.     public void surfaceDestroyed(SurfaceHolder holder) {//此方法为在surfaceView销毁前调用  
  68.     }  
  69. }  

(\src\wyf\zcl\OnDrawThread.java)

[java] view plain copy
  1. package wyf.zcl;  
  2. import android.graphics.Canvas;                 //引入相关包  
  3. import android.view.SurfaceHolder;              //引入相关包  
  4. //该类的作用是时时刷新onDraw,进行画面的重绘  
  5. public class OnDrawThread extends Thread{  
  6.     MySurfaceView msv;      //得到MySurfaceView的引用  
  7.     SurfaceHolder sh;       //SurfaceHolder引用  
  8.     public OnDrawThread(MySurfaceView msv) {  
  9.         super();  
  10.         this.msv = msv;         //构造方法中,将msv引用指向调用了该类的MySurfaceView的对象  
  11.         sh=msv.getHolder();  
  12.     }  
  13.     @Override  
  14.     public void run() {  
  15.         super.run();  
  16.         Canvas canvas = null;   //Canvas的引用  
  17.         while(true){  
  18.             try{  
  19.                 canvas=sh.lockCanvas(null);         //将canvas的引用指向surfaceView的canvas的对象  
  20.                 synchronized(this.sh){              //绘制过程,可能带来同步方面的问题,加锁  
  21.                     if(canvas!=null){  
  22.                     msv.onDraw(canvas);  
  23.                     }  
  24.                 }  
  25.             }finally{  
  26.                 try{  
  27.                         if(sh!=null){  
  28.                             sh.unlockCanvasAndPost(canvas); //绘制完后解锁  
  29.                         }  
  30.                 }catch(Exception e){e.printStackTrace();}  
  31.             }  
  32.             try{  
  33.                 Thread.sleep(Constant.ONDRAWSPEED);                 //休息1秒钟  
  34.             }catch(Exception e){e.printStackTrace();}  
  35.         }  
  36.     }  
  37. }  

(\src\wyf\zcl\PicRunThread.java)

[java] view plain copy
  1. package wyf.zcl;  
  2. //该类是控制duke图片运动的类  
  3. public class PicRunThread extends Thread{  
  4.     MySurfaceView msv;                                  //MySurfaceView的引用  
  5.     private float picX=0;           //图片x坐标  
  6.     private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT;            //图片y坐标  
  7.     boolean yRunFlag=false;     //y方向上的运动标记,false时y=y+speed,true时y=y-speed  
  8.     int picAlphaNum=0;                  //图片变暗效果中画笔的alpha值  
  9.     public PicRunThread(MySurfaceView msv) {  
  10.         super();  
  11.         this.msv = msv;         //将该线程类的引用指向调用其的MySurfaceView的对象  
  12.     }  
  13.     @Override  
  14.     public void run() {  
  15.         super.run();  
  16.         while(true){  
  17.             //控制duke图片的运动  
  18.             while(this.picX<Constant.SCREENWIDTH){           //当图片的左边完全超过屏幕的右边时,循环结束  
  19.                 msv.setPicX(picX);  
  20.                 msv.setPicY(picY);  
  21.                 picX=picX+Constant.PICXSPEED;  
  22.                 if(yRunFlag){//应该向上运动,自减  
  23.                     picY=picY-Constant.PICYSPEED;  
  24.                 }else{//应该向下运动,自加  
  25.                     picY=picY+Constant.PICYSPEED;  
  26.                 }  
  27.                 if(picY<=0){                                 //到达屏幕上沿  
  28.                     yRunFlag=false;  
  29.                 }else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){     //到达屏幕下沿  
  30.                     yRunFlag=true;  
  31.                 }  
  32.                 try{  
  33.                     Thread.sleep(Constant.PICRUNSPEED);  
  34.                 }catch(Exception e){e.printStackTrace();}  
  35.             }  
  36.             //图片变暗效果演示  
  37.             msv.picAlphaFlag=true;                          //开启图片变暗效果  
  38.             for(picAlphaNum=0;picAlphaNum<=255;picAlphaNum++){  
  39.                 if(picAlphaNum==255){  
  40.                     msv.picAlphaFlag=false;                 //当图片变暗效果结束,标记重置  
  41.                     picX=0;         //图片x坐标  
  42.                     picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT;          //图片y坐标  
  43.                     System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);  
  44.                 }  
  45.                 msv.setPicAlphaNum(picAlphaNum);  
  46.                 try{  
  47.                     Thread.sleep(Constant.PICALPHASPEED);  
  48.                 }catch(Exception e){e.printStackTrace();}  
  49.             }  
  50.         }  
  51.     }  
  52. }  

这部分代码对于我这个初学java的人来说比较吃力,但是硬着头皮看了两天,还是基本弄清了这个框架。

代码中涉及一些java的基础知识,我做了一点笔记,如下:


[ extends ]:

一个类使用关键字extends继承其他类,关键字extends出现在类声明时的类名后,
extends后面跟着的是要继承的类的名称,extends实现了继承。在Java中的类只能继承一个类。




[ super ]:

B 继承 A ,B想调用A的方法,那么就可以 用super.A的方法。如果用中文解释:super就是父类的一个别名。



[ implements ]:

implements是一个类实现一个接口用的关键字,
他是用来实现接口中定义的抽象方法
。比如:people是一个接口,他里面有say这个方法。
public interface people()
{
   public say();
}
但是接口没有方法体。
只能通过一个具体的类去实现其中的方法体。
比如chinese这个类,就实现了people这个接口。
 public class chinese implements peopel{ 
   public say()
   {System.out.println("你好!");}
}





[ extendsimplements区别]:

[plain] view plain copy
  1. extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,  
  2. JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,  
  3. 但implements可以实现多个接口,用逗号分开就行了   
  4. 比如   
  5. class A extends B implements C,D,E  
0 0
原创粉丝点击