我尝试在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() {
}
}
}
答案 0 :(得分:6)
1)。首先,使用此代码
protected void layout(int width, int height) {
setExtent(width, height);
}
你实际上是在设置一个非常大的字段。这是因为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));
}
2)。
实际上,touchEvent永远不会被调用
嗯,实际上它确实被调用了。要看到你应该只是触摸(而不是点击)。鼠标左键模拟点击(一系列TouchEvent.DOWN
> TouchEvent.CLICK
> TouchEvent.UNCLICK
> TouchEvent.UP
),右键模拟触摸(一系列{{1 }}> TouchEvent.DOWN
)。
3)。
此外,我在触摸屏幕时出现恼人的“全菜单”。
这是因为您的字段不会消耗TouchEvent.UP
个事件。例如,使用此代码,您的字段将不会显示弹出窗口:
TouchEvent.UNCLICK
但是,对于弹出窗口来说,这是一个糟糕的解决方案。最好先了解真正导致弹出窗口的原因。如果未使用protected boolean touchEvent(TouchEvent message) {
return true;
}
事件,则BB UI框架会调用该字段的TouchEvent.UNCLICK
和getContextMenu(int instance)
方法。因此,为了禁用弹出窗口(实际上是makeContextMenu(ContextMenu contextMenu, int instance)
创建的ContextMenu
,您应该覆盖getContextMenu(int instance)
,如下所示:
getContextMenu(int instance)
4)。最后,我建议不要更改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);
}
方法的原生/默认行为。您可以只观看/记录它,但不要更改(总是调用它的超级版本)。这是因为触摸事件处理比最初看起来更复杂。在这里很容易得到一个棘手的错误。我相信大多数程序员不应该更改touchEvent(TouchEvent message)
的本机行为,除非他们真的想创建一些自定义UI组件来处理触摸手势。通常他们只想对点击作出反应(表现为touchEvent(TouchEvent message)
),但为此你可以简单地覆盖ButtonField
或navigationClick(int status, int time)
。当用户在触摸屏上单击您的字段时,BB UI框架将调用这些方法。
答案 1 :(得分:3)
我想为Arhimed的答案添加额外的信息,因为这似乎是谷歌搜索触摸事件的登陆页面...
我的经历不是与他相矛盾,而是为未来的读者增加可能的解决方案。我正在使用BB OS 5.0。我的经验是使用Storm模拟器和Torch设备。我的应用程序最初是为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)最终我发现了与TouchEvent.UNCLICK
的OP问题类似的东西。找到方法navigationUnClick(int, int)
花了我18个月的时间。与上面的第1点类似,未处理的UNCLICK
成为navigationUnClick(int, int)
来电,也会导致显示上下文菜单。
因此,通过向navigationClick(int, int)
和&添加类似的逻辑navigationUnClick(int, int)
,我能够获得我的列表&接触很好地互动。
这只是补充信息,可能会添加到已接受的版本中。