黑莓中的触摸事件处理



我尝试在黑莓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() {
    }
}

}

1). 首先,使用此代码

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

您实际上是在设置字段的非常大的大小。这是因为 BB UI 框架将最大可用/可能的尺寸传递给layout(int width, int height)因此该字段应使用传递值中的某些部分。在这种特定情况下,宽度将是显示器的宽度(360 px),高度是VerticalFieldManager的最大可能高度(您要向其添加屏幕字段的那个,它隐式存在于屏幕的内部)(1073741823 px)。因此,最后这可能会导致字段需要非常大的Bitmap对象才能绘制,并且您可能会得到一个未捕获的错误"位图太大"(我在 Storm 9530 上做到了)。

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

protected void layout(int width, int height) {
    setExtent(Math.min(width, 360), Math.min(height, 480));
}

2).

实际上,触摸事件永远不会被调用

好吧,实际上它确实被调用了。要看到您应该简单地触摸(而不是单击)。鼠标左键模拟单击(TouchEvent.DOWN> TouchEvent.CLICK> TouchEvent.UNCLICK> TouchEvent.UP序列),右按钮模拟触摸(TouchEvent.DOWN> TouchEvent.UP序列)。

3).

另外,我得到一个烦人的"完整菜单",出现在触摸屏幕上。

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

protected boolean touchEvent(TouchEvent message) {
    return true;
}

但是,对于弹出窗口来说,这是一个糟糕的解决方案。最好了解真正导致弹出窗口的原因。如果未使用TouchEvent.UNCLICK事件,则 BB UI 框架调用字段的getContextMenu(int instance)makeContextMenu(ContextMenu contextMenu, int instance)方法。因此,为了禁用弹出窗口(实际上是由getContextMenu(int instance)创建的ContextMenu,您应该像这样覆盖要getContextMenu(int instance)

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);
}

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

我想

为Arhimed的答案添加额外的信息,因为这似乎是谷歌搜索触摸事件的登录页面......

我的经验不是为了反驳他,而是为未来的读者添加可能的解决方案。我正在使用BB OS 5.0。我的经验是使用风暴模拟器和火炬设备。我的应用程序最初是为OS 4.5编写的,因此它可能在某种兼容模式下运行。

1)正如他的第4点所解释的,如果touchEvent(TouchEvent)返回false,则触摸事件将传递给导航单击事件。如果navigationClick(int, int)返回 false,则会提示系统显示ContextMenu

2)在我的系统上,我找不到方法getContextMenu(int)。所以我无法测试他的第 3 点。我认为这是在 BB6 或更高版本中添加的。

3)我确实找到了getContextMenu() - 即它不需要任何参数。我试图覆盖该方法以返回 null。

奇怪的是,只有在显示初始上下文菜单弹出窗口才会调用此方法!将显示初始上下文菜单弹出窗口 (?),上面有一个用于"完整菜单"的按钮。按下该按钮时,将调用此方法,并可用于填充显示的MainMenu。...奇怪。。。

但是,这意味着覆盖该方法并不能解决我的问题。

4)我无法通过在touchEvent(TouchEvent)中返回true来获得解决方案。我同意这将是糟糕的形式(黑客),但我学会了在BB平台上破解很多。但是,滚动列表字段需要传递触摸事件,以便滚动工作。

5)最终我发现了类似于OP的TouchEvent.UNCLICK问题。我花了18个月的时间才找到navigationUnClick(int, int)的方法。与我上面的第 1 点类似,未处理的UNCLICK成为navigationUnClick(int, int)调用,这也可能导致显示上下文菜单。

因此,通过在navigationClick(int, int)navigationUnClick(int, int)中添加类似的逻辑,我能够让我的列表和触摸很好地交互。


这只是补充信息,可能会添加到接受的 anser 中。

相关内容

  • 没有找到相关文章

最新更新