黑莓:自定义ButtonField消失的焦点突出显示

时间:2011-08-05 17:12:34

标签: blackberry java-me focus field buttonfield

我正在尝试创建一个自定义ButtonField,其焦点(蓝色突出显示颜色)会在几秒钟不活动后消失 - 就像带触摸屏的BB手机上的原始音乐播放器一样。

通过以下示例,我几乎成功了:

screenshot

这是east.png和west.png(由openclipart.org提供):

east

west

这是我的测试代码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,仍然无法正常工作:

enter image description here

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

1 个答案:

答案 0 :(得分:1)

我可能会在调用drawFocus()之前检查_showFocus方法以检查标记super.drawFocus(),然后在onFocus()中将标志设置为true并安排Runnable更改_showFocus标志为false并使其无效(在onUnfocus()中也将其设置为false)。不必担心以这种方式取消定时器或任何东西,因为它只是改变标志并使其无效,使其保持在适当的状态。