Android开发之SurfaceView显示动画效果
Android开发之SurfaceView显示动画效果
发布时间:2015-06-05 来源:查字典编辑
摘要:一、基础知识:SurfaceView继承自View,View负责在主线程中更新动画,而SurfaceView是在一个新线程中更新动画。Sur...

一、基础知识:

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. 界面编辑(reslayoutmain.xml):

[java]

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"

/>

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"

/>

2. 代码编辑:

(srcwyfzclMyActivity.java)

[java]

package wyf.zcl;

/*

* 该例子演示surfaceView中简单场景的绘制

* MyActivity.java 为程序的主Activity

* MySurfaceView.java 为程序的SurfaceView类

* Constant.java 常量类,将常量全部写在该类中

* OnDrawThread.java 该类的作用是时时刷新onDraw,进行画面的重绘

* PicRunThread.java 该类是控制duke图片运动的类

* */

import android.app.Activity; //引入相关包

import android.content.pm.ActivityInfo; //引入相关包

import android.os.Bundle; //引入相关包

import android.view.Window; //引入相关包

import android.view.WindowManager; //引入相关包

public class MyActivity extends Activity {

/** Called when the activity is first created. */

private MySurfaceView msv; //得到surfaceView的引用

@Override

public void onCreate(Bundle savedInstanceState) { //Activity的生命周期函数,该函数是在程序创建时调用

super.onCreate(savedInstanceState);

msv=new MySurfaceView(MyActivity.this); //实例化MySurfaceView的对象

requestWindowFeature(Window.FEATURE_NO_TITLE); //设置屏幕显示没有title栏

getWindow().setFlags(youtParams.FLAG_FULLSCREEN ,

youtParams.FLAG_FULLSCREEN); //设置全屏

//设置只允许横屏

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

setContentView(msv); //设置Activity显示的内容为msv

}

}

package wyf.zcl;

/*

* 该例子演示surfaceView中简单场景的绘制

* MyActivity.java 为程序的主Activity

* MySurfaceView.java 为程序的SurfaceView类

* Constant.java 常量类,将常量全部写在该类中

* OnDrawThread.java 该类的作用是时时刷新onDraw,进行画面的重绘

* PicRunThread.java 该类是控制duke图片运动的类

* */

import android.app.Activity; //引入相关包

import android.content.pm.ActivityInfo; //引入相关包

import android.os.Bundle; //引入相关包

import android.view.Window; //引入相关包

import android.view.WindowManager; //引入相关包

public class MyActivity extends Activity {

/** Called when the activity is first created. */

private MySurfaceView msv; //得到surfaceView的引用

@Override

public void onCreate(Bundle savedInstanceState) { //Activity的生命周期函数,该函数是在程序创建时调用

super.onCreate(savedInstanceState);

msv=new MySurfaceView(MyActivity.this); //实例化MySurfaceView的对象

requestWindowFeature(Window.FEATURE_NO_TITLE); //设置屏幕显示没有title栏

getWindow().setFlags(youtParams.FLAG_FULLSCREEN ,

youtParams.FLAG_FULLSCREEN); //设置全屏

//设置只允许横屏

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

setContentView(msv); //设置Activity显示的内容为msv

}

}

(srcwyfzclConstant.java)

[java]

package wyf.zcl;

import android.view.Display;

//Constant.java 常量类,将常量全部写在该类中

public class Constant {

public static int SCREENWIDTH=480; //屏幕宽(本程序为横屏)

public static int SCREENHEIGHT=320; //屏幕高

public static int PICWIDTH=64; //图片宽度

public static int PICHEIGHT=64; //图片高度

public static int ONDRAWSPEED=30; //onDraw线程类的绘制间隔时间

public static float PICXSPEED=1.5f; //图片水平移动速度

public static float PICYSPEED=2; //图片垂直移动速度

public static int PICRUNSPEED=30; //图片的运动线程的刷新速度

public static int PICALPHASPEED=20; //图片渐暗效果演示刷新速度

}

package wyf.zcl;

import android.view.Display;

//Constant.java 常量类,将常量全部写在该类中

public class Constant {

public static int SCREENWIDTH=480; //屏幕宽(本程序为横屏)

public static int SCREENHEIGHT=320; //屏幕高

public static int PICWIDTH=64; //图片宽度

public static int PICHEIGHT=64; //图片高度

public static int ONDRAWSPEED=30; //onDraw线程类的绘制间隔时间

public static float PICXSPEED=1.5f; //图片水平移动速度

public static float PICYSPEED=2; //图片垂直移动速度

public static int PICRUNSPEED=30; //图片的运动线程的刷新速度

public static int PICALPHASPEED=20; //图片渐暗效果演示刷新速度

}

(srcwyfzclMySurfaceView.java)

[java]

package wyf.zcl;

import android.content.Context; //引入相关包

import android.graphics.Bitmap; //引入相关包

import android.graphics.BitmapFactory; //引入相关包

import android.graphics.Canvas; //引入相关包

import android.graphics.Color; //引入相关包

import android.graphics.Paint; //引入相关包

import android.view.Display; //引入相关包

import android.view.SurfaceHolder; //引入相关包

import android.view.SurfaceView; //引入相关包

public class MySurfaceView extends SurfaceView

implements SurfaceHolder.Callback{

//此处实现SurfaceHolder.Callback接口,为surfaceView添加生命周期回调函数

int dy=Display.DEFAULT_DISPLAY;

MyActivity ma; //得到MyActivity的引用

Paint paint; //画笔的引用

OnDrawThread odt; //OnDrawThread类引用

PicRunThread prt; //图片运动的Thread类引用

private float picX=0; //图片x坐标

private float picY=0; //图片y坐标

boolean picAlphaFlag=false; //图片变暗效果的标记,false为不显示,true为显示。

int picAlphaNum=0; //图片变暗效果中画笔的alpha值

public MySurfaceView(Context context) {

super(context);

this.ma=(MyActivity) context;

//将ma的引用指向调用了该Surfaceview类构造器方法的对象,本例为MyActivity

this.getHolder().addCallback(this); //注册回调接口

paint=new Paint(); //实例化画笔

odt=new OnDrawThread(this); //实例化OnDrawThread类

prt=new PicRunThread(this); //实例化PicRunThread类

prt.start();

}

public void setPicX(float picX) { //图片x坐标的设置器

this.picX = picX;

}

public void setPicY(float picY) { //图片y坐标的设置器

this.picY = picY;

}

public void setPicAlphaNum(int picAlphaNum) {//图片变暗效果alpha参数设置器

this.picAlphaNum = picAlphaNum;

}

@Override

protected void onDraw(Canvas canvas) { //onDraw方法,此方法用于绘制图像,图形等

super.onDraw(canvas);

paint.setColor(Color.WHITE); //设置画笔为白色

canvas.drawRect(0, 0, Constant.SCREENWIDTH, Constant.SCREENHEIGHT, paint);

//此处画了一个白色的全屏幕的矩形,目的是设置背景为白色,同时每次重绘时清除背景

//进行平面贴图

Bitmap bitmapDuke=BitmapFactory.decodeResource(ma.getResources(), R.drawable.duke);

canvas.drawBitmap(bitmapDuke, picX, picY, paint);

//图片渐暗效果

if(picAlphaFlag){

Bitmap bitmapBG=BitmapFactory.decodeResource(ma.getResources(), R.drawable.jpg1);

paint.setAlpha(picAlphaNum);

canvas.drawBitmap(bitmapBG, 0,0, paint);

}

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) { //此方法为当surfaceView改变时调用,如屏幕大小改变。

}

@Override

public void surfaceCreated(SurfaceHolder holder) {//此方法为在surfaceView创建时调用

odt.start(); //启动onDraw的绘制线程

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {//此方法为在surfaceView销毁前调用

}

}

package wyf.zcl;

import android.content.Context; //引入相关包

import android.graphics.Bitmap; //引入相关包

import android.graphics.BitmapFactory; //引入相关包

import android.graphics.Canvas; //引入相关包

import android.graphics.Color; //引入相关包

import android.graphics.Paint; //引入相关包

import android.view.Display; //引入相关包

import android.view.SurfaceHolder; //引入相关包

import android.view.SurfaceView; //引入相关包

public class MySurfaceView extends SurfaceView

implements SurfaceHolder.Callback{

//此处实现SurfaceHolder.Callback接口,为surfaceView添加生命周期回调函数

int dy=Display.DEFAULT_DISPLAY;

MyActivity ma; //得到MyActivity的引用

Paint paint; //画笔的引用

OnDrawThread odt; //OnDrawThread类引用

PicRunThread prt; //图片运动的Thread类引用

private float picX=0; //图片x坐标

private float picY=0; //图片y坐标

boolean picAlphaFlag=false; //图片变暗效果的标记,false为不显示,true为显示。

int picAlphaNum=0; //图片变暗效果中画笔的alpha值

public MySurfaceView(Context context) {

super(context);

this.ma=(MyActivity) context;

//将ma的引用指向调用了该Surfaceview类构造器方法的对象,本例为MyActivity

this.getHolder().addCallback(this); //注册回调接口

paint=new Paint(); //实例化画笔

odt=new OnDrawThread(this); //实例化OnDrawThread类

prt=new PicRunThread(this); //实例化PicRunThread类

prt.start();

}

public void setPicX(float picX) { //图片x坐标的设置器

this.picX = picX;

}

public void setPicY(float picY) { //图片y坐标的设置器

this.picY = picY;

}

public void setPicAlphaNum(int picAlphaNum) {//图片变暗效果alpha参数设置器

this.picAlphaNum = picAlphaNum;

}

@Override

protected void onDraw(Canvas canvas) { //onDraw方法,此方法用于绘制图像,图形等

super.onDraw(canvas);

paint.setColor(Color.WHITE); //设置画笔为白色

canvas.drawRect(0, 0, Constant.SCREENWIDTH, Constant.SCREENHEIGHT, paint);

//此处画了一个白色的全屏幕的矩形,目的是设置背景为白色,同时每次重绘时清除背景

//进行平面贴图

Bitmap bitmapDuke=BitmapFactory.decodeResource(ma.getResources(), R.drawable.duke);

canvas.drawBitmap(bitmapDuke, picX, picY, paint);

//图片渐暗效果

if(picAlphaFlag){

Bitmap bitmapBG=BitmapFactory.decodeResource(ma.getResources(), R.drawable.jpg1);

paint.setAlpha(picAlphaNum);

canvas.drawBitmap(bitmapBG, 0,0, paint);

}

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) { //此方法为当surfaceView改变时调用,如屏幕大小改变。

}

@Override

public void surfaceCreated(SurfaceHolder holder) {//此方法为在surfaceView创建时调用

odt.start(); //启动onDraw的绘制线程

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {//此方法为在surfaceView销毁前调用

}

}

(srcwyfzclOnDrawThread.java)

[java]

package wyf.zcl;

import android.graphics.Canvas; //引入相关包

import android.view.SurfaceHolder; //引入相关包

//该类的作用是时时刷新onDraw,进行画面的重绘

public class OnDrawThread extends Thread{

MySurfaceView msv; //得到MySurfaceView的引用

SurfaceHolder sh; //SurfaceHolder引用

public OnDrawThread(MySurfaceView msv) {

super();

this.msv = msv; //构造方法中,将msv引用指向调用了该类的MySurfaceView的对象

sh=msv.getHolder();

}

@Override

public void run() {

super.run();

Canvas canvas = null; //Canvas的引用

while(true){

try{

canvas=sh.lockCanvas(null); //将canvas的引用指向surfaceView的canvas的对象

synchronized(this.sh){ //绘制过程,可能带来同步方面的问题,加锁

if(canvas!=null){

msv.onDraw(canvas);

}

}

}finally{

try{

if(sh!=null){

sh.unlockCanvasAndPost(canvas); //绘制完后解锁

}

}catch(Exception e){e.printStackTrace();}

}

try{

Thread.sleep(Constant.ONDRAWSPEED); //休息1秒钟

}catch(Exception e){e.printStackTrace();}

}

}

}

package wyf.zcl;

import android.graphics.Canvas; //引入相关包

import android.view.SurfaceHolder; //引入相关包

//该类的作用是时时刷新onDraw,进行画面的重绘

public class OnDrawThread extends Thread{

MySurfaceView msv; //得到MySurfaceView的引用

SurfaceHolder sh; //SurfaceHolder引用

public OnDrawThread(MySurfaceView msv) {

super();

this.msv = msv; //构造方法中,将msv引用指向调用了该类的MySurfaceView的对象

sh=msv.getHolder();

}

@Override

public void run() {

super.run();

Canvas canvas = null; //Canvas的引用

while(true){

try{

canvas=sh.lockCanvas(null); //将canvas的引用指向surfaceView的canvas的对象

synchronized(this.sh){ //绘制过程,可能带来同步方面的问题,加锁

if(canvas!=null){

msv.onDraw(canvas);

}

}

}finally{

try{

if(sh!=null){

sh.unlockCanvasAndPost(canvas); //绘制完后解锁

}

}catch(Exception e){e.printStackTrace();}

}

try{

Thread.sleep(Constant.ONDRAWSPEED); //休息1秒钟

}catch(Exception e){e.printStackTrace();}

}

}

}

(srcwyfzclPicRunThread.java)

[java]

package wyf.zcl;

//该类是控制duke图片运动的类

public class PicRunThread extends Thread{

MySurfaceView msv; //MySurfaceView的引用

private float picX=0; //图片x坐标

private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //图片y坐标

boolean yRunFlag=false; //y方向上的运动标记,false时y=y+speed,true时y=y-speed

int picAlphaNum=0; //图片变暗效果中画笔的alpha值

public PicRunThread(MySurfaceView msv) {

super();

this.msv = msv; //将该线程类的引用指向调用其的MySurfaceView的对象

}

@Override

public void run() {

super.run();

while(true){

//控制duke图片的运动

while(this.picX

msv.setPicX(picX);

msv.setPicY(picY);

picX=picX+Constant.PICXSPEED;

if(yRunFlag){//应该向上运动,自减

picY=picY-Constant.PICYSPEED;

}else{//应该向下运动,自加

picY=picY+Constant.PICYSPEED;

}

if(picY<=0){ //到达屏幕上沿

yRunFlag=false;

}else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){ //到达屏幕下沿

yRunFlag=true;

}

try{

Thread.sleep(Constant.PICRUNSPEED);

}catch(Exception e){e.printStackTrace();}

}

//图片变暗效果演示

msv.picAlphaFlag=true; //开启图片变暗效果

for(picAlphaNum=0;picAlphaNum<=255;picAlphaNum++){

if(picAlphaNum==255){

msv.picAlphaFlag=false; //当图片变暗效果结束,标记重置

picX=0; //图片x坐标

picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //图片y坐标

System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);

}

msv.setPicAlphaNum(picAlphaNum);

try{

Thread.sleep(Constant.PICALPHASPEED);

}catch(Exception e){e.printStackTrace();}

}

}

}

}

package wyf.zcl;

//该类是控制duke图片运动的类

public class PicRunThread extends Thread{

MySurfaceView msv; //MySurfaceView的引用

private float picX=0; //图片x坐标

private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //图片y坐标

boolean yRunFlag=false; //y方向上的运动标记,false时y=y+speed,true时y=y-speed

int picAlphaNum=0; //图片变暗效果中画笔的alpha值

public PicRunThread(MySurfaceView msv) {

super();

this.msv = msv; //将该线程类的引用指向调用其的MySurfaceView的对象

}

@Override

public void run() {

super.run();

while(true){

//控制duke图片的运动

while(this.picX

msv.setPicX(picX);

msv.setPicY(picY);

picX=picX+Constant.PICXSPEED;

if(yRunFlag){//应该向上运动,自减

picY=picY-Constant.PICYSPEED;

}else{//应该向下运动,自加

picY=picY+Constant.PICYSPEED;

}

if(picY<=0){ //到达屏幕上沿

yRunFlag=false;

}else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){ //到达屏幕下沿

yRunFlag=true;

}

try{

Thread.sleep(Constant.PICRUNSPEED);

}catch(Exception e){e.printStackTrace();}

}

//图片变暗效果演示

msv.picAlphaFlag=true; //开启图片变暗效果

for(picAlphaNum=0;picAlphaNum<=255;picAlphaNum++){

if(picAlphaNum==255){

msv.picAlphaFlag=false; //当图片变暗效果结束,标记重置

picX=0; //图片x坐标

picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //图片y坐标

System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);

}

msv.setPicAlphaNum(picAlphaNum);

try{

Thread.sleep(Constant.PICALPHASPEED);

}catch(Exception e){e.printStackTrace();}

}

}

}

}

这部分代码对于我这个初学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("你好!");}

}

[ extends和implements区别]:

[plain]

extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,

JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,

但implements可以实现多个接口,用逗号分开就行了

比如

class A extends B implements C,D,E

extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,

JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,

但implements可以实现多个接口,用逗号分开就行了

比如

class A extends B implements C,D,E

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新安卓软件开发学习
热门安卓软件开发学习
编程开发子分类