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

2 篇文章 0 订阅
1 篇文章 0 订阅

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.dreamman.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方法。最关键的是再也不被繁琐的消息传递机制,控制机制困扰!

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

下次有时间我将一个俄罗斯方块源代码放上,看回调函数是如何将逻辑模块和显示模块有效分割的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值