在Blackberry中触摸事件处理

Rom*_*man 3 events blackberry event-handling touch

我尝试在Blackberry 9550模拟器上实现简单的触摸事件处理,但它不起作用.实际上,touchEvent永远不会被调用,因为控制台中没有出现任何文本.此外,我在触摸屏幕时出现恼人的"全菜单".这是代码:

package mypackage;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EventInjector.TouchEvent;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.VirtualKeyboard;
import net.rim.device.api.ui.container.MainScreen;

public class MyScreen extends MainScreen
{   
public MyScreen()
{    
    super(NO_SYSTEM_MENU_ITEMS);
    getScreen().getVirtualKeyboard().setVisibility(VirtualKeyboard.HIDE_FORCE);      
    add(new HandleTouch());

}

class HandleTouch extends Field {

    protected void layout(int width, int height) {
        setExtent(width, height);
    }

    public void paint(Graphics graphics) {
        graphics.drawBitmap(0, 0, this.getWidth(), this.getHeight(), Bitmap.getBitmapResource("bg.png"), 0, 0);
    }

    public boolean isFocusable() { return true;}

    protected boolean touchEvent(TouchEvent message) {
        switch( message.getEvent() ) {
        case TouchEvent.CLICK:
            System.out.println("----------------------------->CLICK");
            return true;
        case TouchEvent.DOWN:
            System.out.println("----------------------------->DOWN");
            return true;    
        case TouchEvent.MOVE:
            System.out.println("----------------------------->MOVE");
            return true;    
        }
        System.out.println("PRINT ME SOMETHING IN ANY CASE");
        return false;
    }

    public HandleTouch() {

    }
}
Run Code Online (Sandbox Code Playgroud)

}

Vit*_*nko 6

1).首先,使用此代码

protected void layout(int width, int height) {
    setExtent(width, height);
}
Run Code Online (Sandbox Code Playgroud)

你实际上是在设置一个非常大的字段.这是因为BB UI框架传递了最大可用/可能的维度,layout(int width, int height)因此字段应该使用传递值中的某些部分.在这种特定情况下,宽度将是显示器的宽度(360像素),高度是VerticalFieldManager(您正在添加屏幕字段的宽度)的最大可能高度,它隐含地显示在屏幕的内部结构中(1073741823 px) .所以,最后这可能导致一个非常大的Bitmap对象,该字段需要绘制,你可以得到一个未被捕获的错误"位图太大"(我在Storm 9530上做过).

所以,layout()应该使用一些相对较小的值,例如:

protected void layout(int width, int height) {
    setExtent(Math.min(width, 360), Math.min(height, 480));
}
Run Code Online (Sandbox Code Playgroud)

2).

实际上,touchEvent永远不会被调用

嗯,实际上它确实被调用了.要看到你应该只是触摸(而不是点击).鼠标的左键的点击模拟(序列TouchEvent.DOWN> TouchEvent.CLICK> TouchEvent.UNCLICK> TouchEvent.UP),右按钮模拟触摸(序列TouchEvent.DOWN> TouchEvent.UP).

3).

此外,我在触摸屏幕时出现恼人的"全菜单".

这是因为您的字段不消耗TouchEvent.UNCLICK事件.例如,使用此代码,您的字段将不会显示弹出窗口:

protected boolean touchEvent(TouchEvent message) {
    return true;
}
Run Code Online (Sandbox Code Playgroud)

但是,对于弹出窗口来说,这是一个糟糕的解决方案.最好先了解真正导致弹出窗口的原因.如果TouchEvent.UNCLICK没有使用事件,那么BB UI框架调用getContextMenu(int instance)makeContextMenu(ContextMenu contextMenu, int instance)该字段的方法.所以为了禁用弹出窗口(实际上是ContextMenugetContextMenu(int instance)你创建的,你应该覆盖getContextMenu(int instance)像这样的smth:

public ContextMenu getContextMenu(int instance) {
    // just in case check if a context menu is requested
    // in order not to disable other types of menu
    boolean isContextMenu = (Menu.INSTANCE_CONTEXT == instance);
    return isContextMenu ? null : super.getContextMenu(instance);
}
Run Code Online (Sandbox Code Playgroud)

4).最后,我建议不要更改方法的原生/默认行为touchEvent(TouchEvent message).您可以只观看/记录它,但不要更改(始终调用其超级版本).这是因为触摸事件处理比最初看起来更复杂.在这里很容易得到一个棘手的错误.我相信大多数程序员不应该改变原生行为,touchEvent(TouchEvent message)除非他们真的想创建一些自定义UI组件来处理触摸手势.通常他们只是想对点击作出反应(表现为a ButtonField),但是为此你可以简单地覆盖navigationClick(int status, int time)navigationUnclick(int status, int time).当用户在触摸屏上单击您的字段时,BB UI框架将调用这些方法.