我正在尝试创建一个自定义 ButtonField,其焦点(蓝色突出显示颜色)会在几秒钟不活动后消失 - 就像在带触摸屏的 BB 手机上的原始音乐播放器中一样。
通过以下示例,我几乎成功了:
以下是east.png 和 west.png(由 openclipart.org 提供):
这是我的测试代码 MyFocus.java:
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;
public class MyFocus extends UiApplication {
public static void main(String[] args) {
MyFocus app = new MyFocus();
app.enterEventDispatcher();
}
public MyFocus() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
public MyScreen() {
setTitle("2nd trackpad click not working");
getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));
add(new MyButton(MyButton.EAST));
add(new MyButton(MyButton.WEST));
add(NF);
}
class MyButton extends ButtonField {
public final static int EAST = 0;
public final static int WEST = 1;
public final static int WIDTH = 100;
public final static int HEIGHT = 100;
private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
private final Application _app = UiApplication.getUiApplication();
private final static long FOCUS_DURATION = 3000L;
private int _focusTimer = -1;
private final int _direction;
public MyButton(int direction) {
setMargin(EDGES);
setPadding(EDGES);
setImageSize(WIDTH, HEIGHT);
setBorder(VISUAL_STATE_NORMAL,
BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));
setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));
_direction = direction;
switch(_direction) {
case EAST:
setImage(ImageFactory.createImage("east.png"));
break;
case WEST:
setImage(ImageFactory.createImage("west.png"));
break;
}
}
// display red background on long touch and hold
protected boolean touchEvent(TouchEvent event) {
if (event.getEvent() == TouchEvent.CLICK) {
applyThemeOnStateChange();
return true;
}
return super.touchEvent(event);
}
protected void onUnfocus() {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
super.onUnfocus();
}
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyButton.super.onUnfocus();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
public int getPreferredHeight(){
return HEIGHT;
}
public int getPreferredWidth(){
return WIDTH;
}
protected void layout(int width, int height) {
setExtent(WIDTH, HEIGHT);
}
}
}
当我第一次选择一个按钮并等待几秒钟以使其焦点消失时,我的问题是可见的。然后我单击触控板,按下按钮时(已验证),您在屏幕上看不到任何东西 - 它不会变成蓝色或红色。
我已经尝试了 navigationClick() 和 trackwheelUnclick() 的所有组合,但无法解决这个问题。
请问有什么帮助吗?亚历克斯
更新 1:
我尝试了以下方法,但效果不佳(焦点永远消失,可能是因为按钮认为它已经处于所需的视觉状态):
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyButton.this.setBorder(BorderFactory.createSimpleBorder(EDGES));
MyButton.this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
invalidate();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
更新 2:
尝试使用 NullField,仍然无法正常工作:
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;
public class MyFocus extends UiApplication {
public static void main(String[] args) {
MyFocus app = new MyFocus();
app.enterEventDispatcher();
}
public MyFocus() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
static NullField NF = new NullField();
HorizontalFieldManager hfm = new HorizontalFieldManager() {
int lastFocused = -1;
protected int firstFocus(int direction) {
lastFocused = super.firstFocus(direction);
System.out.println("XXX firstFocus: " + lastFocused);
return lastFocused;
}
protected int nextFocus(final int direction, final int axis) {
if (getFieldWithFocus() == NF) {
return lastFocused;
}
lastFocused = super.nextFocus(direction, axis);
System.out.println("XXX nextFocus: " + lastFocused);
return lastFocused;
}
};
public MyScreen() {
setTitle("2nd trackpad click not working");
getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));
hfm.add(new MyButton(MyButton.WEST));
hfm.add(new MyButton(MyButton.EAST));
hfm.add(new MyButton(MyButton.EAST));
hfm.add(NF);
add(hfm);
}
class MyButton extends ButtonField {
public final static int EAST = 0;
public final static int WEST = 1;
public final static int WIDTH = 100;
public final static int HEIGHT = 100;
private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
private final Application _app = UiApplication.getUiApplication();
private final static long FOCUS_DURATION = 3000L;
private int _focusTimer = -1;
private final int _direction;
public MyButton(int direction) {
setMargin(EDGES);
setPadding(EDGES);
setImageSize(WIDTH, HEIGHT);
setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));
setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));
_direction = direction;
switch(_direction) {
case EAST:
setImage(ImageFactory.createImage("east.png"));
break;
case WEST:
setImage(ImageFactory.createImage("west.png"));
break;
}
}
protected boolean touchEvent(TouchEvent event) {
if (event.getEvent() == TouchEvent.CLICK) {
applyThemeOnStateChange();
return true;
}
return super.touchEvent(event);
}
protected void onUnfocus() {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
super.onUnfocus();
}
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyScreen.NF.setFocus();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
public int getPreferredHeight(){
return HEIGHT;
}
public int getPreferredWidth(){
return WIDTH;
}
protected void layout(int width, int height) {
setExtent(WIDTH, HEIGHT);
}
}
}