博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
J2ME编程最佳实践之屏幕导航
阅读量:4043 次
发布时间:2019-05-24

本文共 2308 字,大约阅读时间需要 7 分钟。

除了游戏程序,在通常的midp应用程序中,通常会有很多个screen或canvas,这些屏幕一般靠命令来实现切换,比如用户点击“next”应该跳到下一屏,点击“back”应该返回到上一屏。当屏幕数量相当可观时,如何在各个屏幕之间导航就值得好好考虑了。

  经典的mvc模式可用于屏幕导航,model用于存储应用程序数据,而view则是各个displayable对象,controller需要单独的一个类实现。由于midlet类本身在生命周期内就只有一个实例,因此midlet类就非常适合作为controller。sun在blueprints示例程序smartticket中应用了非常复杂的mvc,完全可以满足midp应用程序的导航需要,但是可以看出,缺点是很明显的:

  一是每一个事件都需要一个唯一标识,switch-case语句会随着屏幕的增加而增加,controller变得难以维护。二是controller引用了所有的view,这些view在程序启动时就被初始化导致很大的内存开销,而不管它们是否会被显示。三是大量的model对象以及异常处理都使得整个应用程序的逻辑大大复杂。

  实际上,midp应用程序的很多屏幕并不需要复杂的controller和model,我们的目标是满足基本的灵活性的同时保持结构简单。因此,另外两种导航方法是用二叉树和堆栈实现,这里我们只讨论用堆栈实现的midp导航框架,其基本思想是:每当前进到下一个屏幕时,先将下一个屏幕压栈,然后再显示;当返回到上一个屏幕时,先从堆栈中弹出当前屏幕,再从堆栈中取出上一个屏幕并显示。因此,每个屏幕只需要指定要显示的下一个屏幕,而不需记住上一个屏幕。这种堆栈导航模型特别适合有规律的“前进”、“后退”屏幕。

  由于midlet类运行期只有一个实例,因此,使用midlet类作为控制器相当合适。此外,我们在一个静态变量中保存了midlet实例,使得访问midlet更加方便:

public class controllermidlet extends midlet {
private static controllermidlet instance = null;
private display display = null;
private stack ui = new stack();
public controllermidlet() { instance = this; }
protected void startapp() {}
protected void pauseapp() {}
protected void destroyapp(boolean unconditional) {}
public static void goback() {
instance.ui.pop();
object obj = instance.ui.peek();
instance.display.setcurrent((displayable)obj);
}
public static void forward(displayable next) {
instance.ui.push(next);
instance.display.setcurrent(next);
}
}

  让我们更详细地研究一下实际的应用程序可能出现的几种屏幕跳转情况。最简单的情况是,从一个屏幕前进到另一个屏幕,且返回时仍回到原先的屏幕,这种情况完全符合堆栈的fifo特点,可以直接调用controllermidlet的forward和goback方法即可。例如,要显示一个帮助屏幕:

  对于一个联网的应用程序,另一种情况是有一个暂时的等待屏幕。下面是一个在线浏览图片的屏幕:

  与上面的情况所不同的是,如果用户在屏幕3选择“返回”,则应当回到屏幕1而不是屏幕2,因此,对于屏幕2到屏幕3的切换,就不能forward,我们使用replace,抛弃屏幕2,从而实现屏幕3直接可以goback到屏幕1:

public static void replace(displayable next) {
instance.ui.pop();
instance.ui.push(next);
instance.display.setcurrent(next);
}

  堆栈的变化如下:

  对于某些更为复杂的情况,例如,登录过程,如果允许用户选择自动登录,则屏幕跳转如下:

  如果用户不选择自动登录,则屏幕跳转如下:

  对于这种情况,解决方案是,即使用户选择了自动登录,loginui屏幕也要被压入堆栈中,但是不显示出来,因此,我们定义了另一个forward(displayable d1, displayable d2)方法,它将d1和d2依次压入堆栈,但只显示d2。在返回时,如果用户取消,则返回到loginui。总之,通过定义多个导航方法,就可以实现各种操作。

  这种基于堆栈的导航模型非常适用于有规律的“前进”,“后退”屏幕,而且只在需要的时候生成新的屏幕。无需关心屏幕状态,因为返回时上一个屏幕的状态被完整地保存在堆栈中。

  堆栈模型的缺点是数据由不同的屏幕处理,对于一些流程而言,可能需要将每个屏幕的数据依次传递给下一个屏幕,越往后的屏幕其构造方法的参数可能也越多。

  对于联网操作等涉及到多线程等待屏幕的情况,我们将在后面给出一个完整的解决方案,并集成到堆栈导航框架中,使应用程序本身完全不用涉及到多线程联网操作,只需专注于自身逻辑。

转载地址:http://rdedi.baihongyu.com/

你可能感兴趣的文章
yuv420 还原为RGB图像
查看>>
LED恒流驱动芯片
查看>>
驱动TFT要SDRAM做为显示缓存
查看>>
使用file查看可执行文件的平台性,x86 or arm ?
查看>>
qt5 everywhere 编译summary
查看>>
qt5 everywhere编译完成后,找不到qmake
查看>>
qt 创建异形窗体
查看>>
可重入函数与不可重入函数
查看>>
简单Linux C线程池
查看>>
内存池
查看>>
输入设备节点自动生成
查看>>
GNU hello代码分析
查看>>
Qt继电器控制板代码
查看>>
wpa_supplicant控制脚本
查看>>
gstreamer相关工具集合
查看>>
RS232 四入四出模块控制代码
查看>>
gstreamer插件之 videotestsrc
查看>>
linux 驱动开发 头文件
查看>>
/etc/resolv.conf
查看>>
container_of()传入结构体中的成员,返回该结构体的首地址
查看>>