您的位置:首页 > 编程语言 > Java开发

java回调函数的应用,andriod简单2d动画显示!

2014-02-16 14:13 344 查看
andriod开发界面显示有一个小问题,便是主线程才能更新view,但是主线程又不能承担耗时操作,如果开发一个比较复杂的一个小游戏,界面显示就会出现问题。

andriod提供了一个替代的类SurfaceView,它能够在界面上挖一块出来,显示自己的界面,关键是它的显示可以由任意线程使用。

但是SurfaceView的使用却异常繁琐,写法也千奇百怪,而且很多时候,我们其实只是需要将一些不停运动的画面显示在界面上而已。

而在界面上绘图,我们甚至不关心它到底怎么实现画图的功能,我们只是想要拿到这个绘图区域的大小,和绘画所需的一个类Canvas而已。

为什么我们不将surfaceview的具体实现都封装起来,让后将canvas和界面大小提供给外界呢?

如何实现这样的功能,yes 回调函数!

看具体代码:

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.graphics.Rect;

import android.util.AttributeSet;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

public class Draw2dAutoFlush extends SurfaceView implements Callback{
public Draw2dAutoFlush(Context context){
this(context,null);
}

public Draw2dAutoFlush(Context context, AttributeSet attrs) {
super(context, attrs);
sfh=getHolder();
sfh.addCallback(this);
this.requestFocus();
}
private SurfaceHolder sfh=null;
private int delaytime=500;
private MThread mthread=null;
/**自动刷新*/
public void refresh(){
draw2d();
}
public void start(){
mthread=new MThread();
alive=true;
mthread.start();

}
private boolean alive=false;
private class MThread extends Thread{

@Override
public void run() {
while(alive){
try {
sleep(delaytime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
draw2d();
}
}

}
private Canvas canvas;
private void draw2d() {

canvas=sfh.lockCanvas();
ondraw.draw(canvas, getLeft(), getTop(), getRight(), getBottom());
sfh.unlockCanvasAndPost(canvas);
}
private OnAutodraw ondraw=null;
public void setOnAutodraw(OnAutodraw onAutodraw){
ondraw=onAutodraw;
}

public int getDelaytime() {
return delaytime;
}
/**设置刷新频率*/
public void setDelaytime(int delaytime) {
this.delaytime = delaytime;
}

/**线程是否存活*/
public boolean isAlive() {
return alive;
}

public void setAlive(boolean alive) {
this.alive = alive;
}
/**必须实现此类中的方法来进行自动刷新画面**/
public interface OnAutodraw{
publicvoid draw(Canvas canvas,int left,int top,int right,int bottom);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
alive=false;
mthread=null;
}

}  

如上代码虽然有些小长,但是我设计之初为的便是能够自动更新图片。所以特意添加了一个线程类,线程类其实用Timer类实现更加完美。

这么长的代码其实主要作用便是将public void draw(Canvas canvas,int left,int top,int right,int bottom);方法暴露给外界,将canvas,和长宽高给外界。

那么怎么用他,看Activity代码:

package com.example.draw2dframe;

import android.app.Activity;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.os.Bundle;

import android.view.Menu;

import com.dreamman.draw.Draw2dAutoFlush;

import com.dream
4000
man.draw.Draw2dAutoFlush.OnAutodraw;

public class MainActivity extends Activity {
Draw2dAutoFlush daf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
daf=new Draw2dAutoFlush(this);
daf.setOnAutodraw(new OnAutodraw() {

@Override
public void draw(Canvas canvas, int left, int top, int right, int bottom) {
Paint paint=new Paint();
paint.setColor(0xffffffff);
...........;
}
});
setContentView(daf);
daf.start();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}

简单的代码,3步,1>>拿到 Draw2dAutoFlush(this);2>>daf.setOnAutodraw(new OnAutodraw() {});3>>daf.start();

在外界调用SurfaceView以后再也不需要考虑怎么写holder怎么添加线程,它更多像一个按钮监听,当然实时的更新可以调用sdf的refresh方法。最关键的是再也不被繁琐的消息传递机制,控制机制困扰!

当然这个类并没有最优化实现,只是抛出一个回调函数的应用,来揭示封装的好处。帮助大家对通用编程的理解。而且如果要学习框架对这个一定要理解透彻才行。

下次有时间我将一个俄罗斯方块源代码放上,看回调函数是如何将逻辑模块和显示模块有效分割的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java andriod 框架 动画