版权所有,转载请注明来自 : http://mdev.cc SinFrancis
版权所有,转载请注明来自 :http://www.iteye.com/topic/544916
有JE的朋友问我关于BB上捕捉按键的一些问题,总结了一下,写了此文章。
BB上的所有UI视图的父类是一个叫做Field的类,此类中有keyDown keyChar等相关的方法。
那么BB上并不能像Android上可以直接对某个组件进行set监听事件的方法,那么我们应该怎么样做呢?
我们可以重写这些关于key的方法。
那么分析一下这些方法如何运行的:
BB上的最外层的组件是Screen,此组件中可以包含Manager 、Field等子类,那么当按下某个键的时候,系统会捕获到
这个按键的值,然后传递给Screen,Screen的决定是否要处理此消息,如果处理的话,就不再传递给子组件处理,如果不处理,那么就会交给子组件中当前聚焦的那个组件来处理,写的比较难懂。。。
举个例子:
我们在Screen类中重写了 keyDown方法,例如:
- System.out.println("Screen1.keyDown():"+keycode);
- return true;
- }
protected boolean keyDown(int keycode, int time) {
System.out.println("Screen1.keyDown():"+keycode);
return true;
}
此方法返回true,那么表示当前key事件由Screen处理,不会再往下传递给子组件。如果返回false则反之。
如果Screen或者父组重写了捕捉key事件的方法,并且返回true,那么子组件是接收不到消息的。
关于keyDown和keyChar两个方法。keyDown优先于keyChar,如果一个组件中这个两个方法同时被重写,并且keyDown返回了true,那么keyChar是不能被调用的。
请看代码:
- import net.rim.device.api.ui.Keypad;
- import net.rim.device.api.ui.UiApplication;
- import net.rim.device.api.ui.component.ActiveRichTextField;
- import net.rim.device.api.ui.container.MainScreen;
- /**
- * @site http://androidos.cc http://mdev.cc
- * @author SinFrancis Wong
- * @since 2009-12-09
- *
- */
- public class Main extends UiApplication {
- public Main() {
- pushScreen(new Screen1());
- }
- public static void main(String[] args) {
- Main m = new Main();
- m.enterEventDispatcher();
- }
- }
- class Screen1 extends MainScreen {
- ActiveRichTextField f;
- public Screen1() {
- f = new ActiveRichTextField("catch key....") {
- protected boolean keyChar(char c, int status, int time) {
- //keyChar方法似乎捕捉不到menu按键事件,可以用keyDown捕捉
- System.out.println(".keyChar():"+c);
- if (c == Keypad.KEY_BACKSPACE) {
- //捕捉Back space键
- f.setText("catch the KEY_BACKSPACE key...");
- return true;
- } else if (c == Keypad.KEY_ESCAPE) {
- //捕捉back键
- f.setText("catch the BACK key...");
- return true;
- } else {
- f.setText("catch other key value is :" + c);
- return true;
- }
- }
- protected boolean keyDown(int keycode, int time) {
- if (keycode == 268566528) {//menu的int值
- f.setText("catch the MENU key...");
- }
- System.out.println(".keyDown():"+keycode);
- return false;
- }
- };
- add(f);
- }
- protected boolean keyDown(int keycode, int time) {
- System.out.println("Screen1.keyDown():"+keycode);
- return false;//交给子组件处理
- }
- }
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ActiveRichTextField;
import net.rim.device.api.ui.container.MainScreen;
/**
* @site http://androidos.cc http://mdev.cc
* @author SinFrancis Wong
* @since 2009-12-09
*
*/
public class Main extends UiApplication {
public Main() {
pushScreen(new Screen1());
}
public static void main(String[] args) {
Main m = new Main();
m.enterEventDispatcher();
}
}
class Screen1 extends MainScreen {
ActiveRichTextField f;
public Screen1() {
f = new ActiveRichTextField("catch key....") {
protected boolean keyChar(char c, int status, int time) {
//keyChar方法似乎捕捉不到menu按键事件,可以用keyDown捕捉
System.out.println(".keyChar():"+c);
if (c == Keypad.KEY_BACKSPACE) {
//捕捉Back space键
f.setText("catch the KEY_BACKSPACE key...");
return true;
} else if (c == Keypad.KEY_ESCAPE) {
//捕捉back键
f.setText("catch the BACK key...");
return true;
} else {
f.setText("catch other key value is :" + c);
return true;
}
}
protected boolean keyDown(int keycode, int time) {
if (keycode == 268566528) {//menu的int值
f.setText("catch the MENU key...");
}
System.out.println(".keyDown():"+keycode);
return false;
}
};
add(f);
}
protected boolean keyDown(int keycode, int time) {
System.out.println("Screen1.keyDown():"+keycode);
return false;//交给子组件处理
}
}
以上代码在BB 9500机器上测试是正常捕捉按键事件的。
如果将最后的一段keyDown代码返回true,点击是没有任何反应得(在debug模式下能看到打印的消息),因为消息没有往下传递,全部被Screen消耗掉了。
- protected boolean keyDown(int keycode, int time) {
- System.out.println("Screen1.keyDown():"+keycode);
- return true;//交给子组件处理
- }
protected boolean keyDown(int keycode, int time) {
System.out.println("Screen1.keyDown():"+keycode);
return true;//交给子组件处理
}