我正在尝试创建一个自定义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);
}
}
}
答案 0 :(得分:1)
我可能会在调用drawFocus()
之前检查_showFocus
方法以检查标记super.drawFocus()
,然后在onFocus()
中将标志设置为true并安排Runnable更改_showFocus
标志为false并使其无效(在onUnfocus()
中也将其设置为false)。不必担心以这种方式取消定时器或任何东西,因为它只是改变标志并使其无效,使其保持在适当的状态。