2

我正在一个 BlackBerry 应用程序中工作,我需要在其中使用底部的选项卡。

早些时候,我已经使用了选项卡,但位于屏幕顶部。要将选项卡放在屏幕底部,我使用了该sublayout()方法。但是这样做的副作用是我现在不能使用该display(index)方法。每次当我单击任何选项卡时,只会选择第一个选项卡。当我隐藏sublayout()方法时,一切正常。

这是我正在使用的代码:

TabControl.java

public class TabControl extends MainScreen{
    public static int tabHeight = 0;
    public static TabField mTabField = null;
    public static Bitmap BACKGROUND_IMAGE = Bitmap
    .getBitmapResource("Background_Superhero.png");
    private UiApplication uiApp = UiApplication.getUiApplication();
    private UiEngine ui = Ui.getUiEngine();
    private int displayHieght;
    public TabControl(BuddyListField buddyList) {
        super(MainScreen.NO_VERTICAL_SCROLL);
    }
    public void addFields() {
        try {
            mTabField = new TabField(this);
            add(mTabField);
            HomeTab home = new HomeTab();
            mTabField.addTab(Bitmap.getBitmapResource("home_tab.png"), home,
                    Field.FOCUSABLE);
            SettingTab setting = new SettingTab();
            mTabField.addTab(Bitmap.getBitmapResource("Setting_tab.png"), setting,
                    Field.FOCUSABLE);
            AboutTab about = new AboutTab();
            mTabField.addTab(Bitmap.getBitmapResource("abouttab.png"), about,
                    Field.FOCUSABLE);

            mTabField.setDefault(Constant.SETTING_TAB_INDEX);
        } catch (Exception e) {
            System.out.println(e+"=-====>>TabControl");
            e.printStackTrace();
        }
    }
    protected boolean keyDown(int keycode, int time) {
        if (keycode == 1769472) {
            // escape pressed
            return true;
        }
        return super.keyDown(keycode, time);
    }
}

TabField.java

public class TabField extends VerticalFieldManager {


    private static Bitmap tabBackGroundImage = Bitmap
    .getBitmapResource("tab_bar.png");
    private Background CONTROL_NORMAL_BG = BackgroundFactory
    .createBitmapBackground(tabBackGroundImage);
    private Background CONTROL_ACTIVE_BG = BackgroundFactory
    .createSolidBackground(Color.SILVER);

    public static int indexValue = 0;
    private static int mCurrentIndex = 0;
    private int mDefault = 0;

    private Field mCurrentField = null;
    private Vector mTabFields = new Vector();
    private MainScreen _mainscreen = null;
    private HorizontalFieldManager mTabController = new HorizontalFieldManager();

    private UiApplication uiApp = UiApplication.getUiApplication();
    private UiEngine ui = Ui.getUiEngine();
    private int tabHieght;
    private int displayHieght;


    public TabField(MainScreen mainscreen) {
        super(MainScreen.USE_ALL_HEIGHT);
        _mainscreen = mainscreen;
        displayHieght = Display.getHeight();

        add(mTabController);
        SeparatorField separatorField = new SeparatorField();
        separatorField.setBackground(CONTROL_ACTIVE_BG);
        add(separatorField);

    }

    public void setDefault(int index) {
        mDefault = index;
        if (mDefault <= mTabFields.size() - 1) {
            display(mDefault);
        }
    }

    public void display(int index) {
        VirtualKeyboard virtKbd = _mainscreen.getVirtualKeyboard();
        if(virtKbd != null)
            virtKbd.setVisibility(VirtualKeyboard.RESTORE);

        try {
            if (mCurrentField != null) {
                if (mCurrentField instanceof TabFieldItem) {
                    ((TabFieldItem) mCurrentField).onUnSelected();
                }
                delete(mCurrentField);
            }
            mCurrentField = (Field) mTabFields.elementAt(index);
            add(mCurrentField);
            mCurrentField.setFocus();

            if (mCurrentField instanceof TabFieldItem) {
                ((TabFieldItem) mCurrentField).onSelected();
            }

            setDirty(false);
            BitmapField mCurrentBG = (BitmapField) mTabController
            .getField(mCurrentIndex);

            mCurrentBG.setBackground(CONTROL_NORMAL_BG);
            mCurrentBG.setBitmap(getOnUnFocusImg(mCurrentIndex));
            BitmapField mBG = (BitmapField) mTabController.getField(index);
            mBG.setBackground(CONTROL_ACTIVE_BG);
            mBG.setBitmap(getOnFocusImg(index));
            mCurrentIndex = index;
            if(virtKbd != null)
                virtKbd.setVisibility(VirtualKeyboard.HIDE);
            if (indexValue == 3) {


            }
        } catch (Exception e) {
            System.out.println("Exception: In TabField--->display() "
                    + e.toString());
        }
    }

    public void addTab(Bitmap aBitmap, final Field aTabField, long style) {
        BitmapField lButton = null;
        if (style == Field.FOCUSABLE) {
            final BitmapField focusbleButton = new BitmapField(aBitmap,
                    Field.FOCUSABLE) {
                protected boolean navigationClick(int status, int time) {
                    if (aTabField == null) {
                        return false; 
                    }
                    indexValue = getIndex();
                    display(indexValue);
                    return true;
                }

                protected void paint(Graphics graphics) {
                    if (indexValue == getIndex()) {
                        graphics.setBackgroundColor(Color.SILVER);
                        graphics.clear();
                    }
                    super.paint(graphics);
                }

                public void setSpace(int hSpace, int vSpace) {

                    super.setSpace(hSpace, vSpace);
                }
            };
            focusbleButton.setBackground(CONTROL_NORMAL_BG);
            setlButtonSpace(focusbleButton);
            lButton = focusbleButton;
        } else {
            lButton = new BitmapField(aBitmap);
        }
        /*if (WallpaperMainScreen.tabHeight == 0)
            WallpaperMainScreen.tabHeight = lButton.getBitmapHeight();*/
        mTabController.add(lButton);
        mTabFields.addElement(aTabField);

        if (mDefault == mTabFields.size() - 1 && aTabField != null) {
            display(mDefault);
        }
    }

    //SUBLAYOUT METHOD USED TO BRING THE TABBAR AT THE BOTTOM OF THE SCREEN---------------
    protected void sublayout(int maxWidth, int maxHeight) {
        super.sublayout(maxWidth, maxHeight);
        tabHieght = mTabController.getHeight();
        int y = displayHieght - tabHieght;
        setPositionChild(mTabController, 0, y);
    }


    private void setlButtonSpace(BitmapField lButton) {
        int tabWidth = Display.getWidth() / 3;
        int imagewidth = lButton.getBitmapWidth();
        int imageheight = lButton.getBitmapHeight();
        int hPaddingValue = (tabWidth - imagewidth) / 2;
        int vPaddingValue = (tabWidth - imageheight) / 7;
        lButton.setSpace(hPaddingValue + 1, vPaddingValue);
    }

    private Bitmap getOnFocusImg(int index) {
        Bitmap image = null;
        switch (index) {
        case 0:
            image = Bitmap.getBitmapResource("home_tab.png");
            break;
        case 1:
            image = Bitmap.getBitmapResource("Setting_tab.png");
            break;
        case 2:
            image = Bitmap.getBitmapResource("about_tab.png");
            break;
        /*case 3:
            image = Bitmap.getBitmapResource("exit_tab.png");
            break;
*/
        }
        return image;
    }

    private Bitmap getOnUnFocusImg(int currentIndex) {
        Bitmap image = null;
        switch (currentIndex) {
        case 0:
            image = Bitmap.getBitmapResource("home_tab.png");
            break;
        case 1:
            image = Bitmap.getBitmapResource("Setting_tab.png");
            break;
        case 2:
            image = Bitmap.getBitmapResource("about_tab.png");
            break;
        /*case 3:
            image = Bitmap.getBitmapResource("exit_tab.png");
            break;*/
        }
        return image;

    }


    protected boolean keyChar(char ch, int status, int time) {
        if (mCurrentField != null && mCurrentField instanceof TabFieldItem) {
            return ((TabFieldItem) mCurrentField).keyChar(ch, status, time);
        } else {
            return super.keyChar(ch, status, time);
        }
    }
}

TabFieldItem.java

package com.np.custom;

public interface TabFieldItem {
    /**
     * Method invoked when the tabField is about to be displayed
     */
    public void onSelected();

    /**
     * Method invoked when the tabField is about to be removed from the display
     */
    public void onUnSelected();

    public boolean keyChar(char ch, int status, int time);

}

我在 TabField.java 类中使用了 sublyout 方法。结果如图所示。

在此处输入图像描述

4

5 回答 5

1

在“add(mTabController)”上方添加一个管理器,并将该管理器的固定高度覆盖子布局并在子布局内设置 setextent,高度必须为 displayheight-mtabcontroller 高度。并删除 tabfield 类中覆盖的子布局。

于 2012-08-03T08:29:32.023 回答
1

我有一些建议。

首先,在构建这样的东西时,尤其是对于 BlackBerry,很难获得所有的点击处理,或者正确的焦点处理。从 RIM 的一个例子开始通常是个好主意,你知道它是有效的。在这种情况下,您可以在此处查看他们的 Tab Bar 示例

如果您想坚持使用您的代码,我发现有几件事可能存在问题:

//SUBLAYOUT METHOD USED TO BRING THE TABBAR AT THE BOTTOM OF THE SCREEN---------------
protected void sublayout(int maxWidth, int maxHeight) {
    super.sublayout(maxWidth, maxHeight);
    tabHieght = mTabController.getHeight();
    int y = displayHieght - tabHieght;
    setPositionChild(mTabController, 0, y);
}
  1. 当您实施 时sublayout(),您通常应该为您拥有的每个子字段调用setPositionChild()和。你只是在打电话。通常,打电话也是合适的。layoutChild()ManagersetPositionChild()setExtent()

  2. 我最近看到了一堆问题,人们覆盖VerticalFieldManager(或HorizontalFieldManager)然后仍然覆盖sublayout()以提供自定义布局管理。这违背了VerticalFieldManager首先使用的目的,因为它为您执行垂直布局,按照您的顺序排列子字段add()。如果您想要任何自定义,我建议您扩展Manager,而不是VerticalFieldManager. 如果默认VerticalFieldManager布局不是您想要的,那么只需提供所需的完整实现即可Manager。这不是很困难。只需执行sublayout(),getPreferredWidth()getPreferredHeight().

当然,您仍然需要sublayout()正确实施(参见上面的1.)。

无论如何,发布类似问题的其他人也看到了奇怪的行为,直到他们将他们的班级(TabField为你)改为extends Manager。这就是我首先要尝试解决的问题。

于 2012-07-29T09:43:49.573 回答
1

尝试使用setStatus(mTabField)而不是覆盖子布局。

于 2012-07-29T02:30:50.917 回答
0

对于选项卡栏示例,在 Blackberry JDE(4.5 及更高版本)中创建新项目

只需复制下面的代码并执行它。

MyTabAppDemo.java

package com.app;

import net.rim.device.api.ui.UiApplication;

public class MyTabAppDemo extends UiApplication
{   public static void main(String[] args)
    {   MyApp theApp = new MyApp();       
        theApp.enterEventDispatcher();
    }
    public MyApp()
    {             
        pushScreen(new TabScreenExample());
    }    
}

TabScreenExample.java

package com.app;

import net.rim.device.api.system.Application;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;

public class TabScreenExample extends MainScreen {
    private VerticalFieldManager mainManager;
    private NavigationMenuBar tabBar;

    public TabScreenExample() {
        tabBar = new NavigationMenuBar() {

            public void onNavigationClick(int selection) {
                if (NavigationMenuBar.TAB1 == selection) {
                    // Push Screen Which is releted to first tab
                    synchronized (Application.getEventLock()) {
                        UiApplication.getUiApplication().pushScreen(new Screan1());
                    }
                } else if (NavigationMenuBar.TAB2 == selection) {
                    // Push Screen Which is releted to second tab
                    synchronized (Application.getEventLock()) {
                        UiApplication.getUiApplication().pushScreen(new Screan2());
                    }
                }
            }
        };
        mainManager = new VerticalFieldManager() {
            protected void sublayout(int maxWidth, int maxHeight) {
                super.sublayout(maxWidth, maxHeight);
                setExtent(getPreferredWidth(), getPreferredHeight());
            }

            public int getPreferredWidth() {
                return Display.getWidth();
            }

            public int getPreferredHeight() {
                return Display.getHeight() - tabBar.getPreferredHeight();
            }
        };

        add(mainManager);
        add(tabBar);
    }
}

// 这里是自定义标签栏.. 在这个标签栏中你可以添加很多标签。

导航菜单栏.java

package com.app;

import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.KeypadUtil;
import net.rim.device.api.ui.container.HorizontalFieldManager;

public abstract class NavigationMenuBar extends HorizontalFieldManager {

    public static final int TAB1 = 0;
    public static final int TAB2 = 1;

    // Create object of tabs
    private TopBarComponenet tab1;
    private TopBarComponenet tab2;

    // Selected Tab;
    private int currentState;

    // tab Normal Image
    private Bitmap imgTab1Normal, imgTab2Normal;

    // tab Focus Image
    private Bitmap imgTab1Focus, imgTab2Focus;

    public NavigationMenuBar() {

        // Normal Images
        imgTab1Normal = Bitmap.getBitmapResource("tab1Normal.png");
        imgTab2Normal = Bitmap.getBitmapResource("tab2Normal.png");

        // Focus Images
        imgTab1Focus = Bitmap.getBitmapResource("tab1Focus.png");
        imgTab2Focus = Bitmap.getBitmapResource("tab2Focus.png");

        // create first tab
        tab1 = new TopBarComponenet(imgTab1Normal) {

            protected void onClick() {
                currentState = TAB1;
                selectTab(currentState);
            }
        };
        // create Second tab
        tab2 = new TopBarComponenet(imgTab2Normal) {

            protected void onClick() {
                currentState = TAB2;
                selectTab(currentState);
            }
        };

        // add tab button in horizontal manager.
        add(tab1);
        add(tab2);
    }

    public int getPreferredHeight() {
        return imgTab1Normal.getHeight();
    }

    public void selectTab(int tab) {
        synchronized (Application.getEventLock()) {
            // Set Tab visible GUI
            if (tab == TAB1) {
                tab1.setFocus();
                tab1.setBgImage(imgTab1Focus);
                tab2.setBgImage(imgTab2Normal);
                tab1.selected = true;
                tab2.selected = false;
            } else if (tab == TAB2) {
                tab2.setFocus();
                tab1.setBgImage(imgTab1Normal);
                tab2.setBgImage(imgTab2Focus);
                tab1.selected = false;
                tab2.selected = true;
            }
        }
        currentState = tab;
        onNavigationClick(currentState);
    }

    public void deselectAllTab() {
        tab1.setBgImage(imgTab1Normal);
        tab2.setBgImage(imgTab2Normal);
        tab1.selected = false;
        tab2.selected = false;
    }

    public abstract void onNavigationClick(int selection);

    protected void sublayout(int maxWidth, int maxHeight) {
        super.sublayout(maxWidth, maxHeight);
        setExtent(Display.getWidth(), getPreferredHeight());
    }

    protected void paintBackground(Graphics gr) {
        // TODO Auto-generated method stub
        super.paintBackground(gr);
        gr.setColor(0x000000);
        gr.fillRect(0, 0, Display.getWidth(), getPreferredHeight());
    }

    private abstract class TopBarComponenet extends Field {

        private Bitmap bgImage;
        private String text;
        public boolean selected;
        private int width;
        private int height;

        public TopBarComponenet(final Bitmap bgImage) {
            super(FOCUSABLE);
            this.bgImage = bgImage;
            // this width depends on how many tab added.
            // for example if we want to add 5 tab then
            // width = Display.getWidth() / 5;
            width = Display.getWidth() / 2;
            height = bgImage.getHeight();
        }

        public void setBgImage(Bitmap image) {
            this.bgImage = image;
        }

        protected void drawFocus(Graphics graphics, boolean on) {
        }

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

        public int getPreferredHeight() {
            return height;
        }

        public int getPreferredWidth() {
            return width;
        }

        protected void paint(Graphics graphics) {
            graphics.drawBitmap((width - bgImage.getWidth()) / 2, 0,
                    bgImage.getWidth(), bgImage.getHeight(), bgImage, 0, 0);
            if (isFocus()) {
                graphics.setColor(0xffffff); // white
                graphics.setGlobalAlpha(50);
                graphics.fillRoundRect(0, 2, width, height - 4, 10, 10);
                graphics.setGlobalAlpha(255);
            }
        }

        protected void onFocus(int direction) {
            super.onFocus(direction);
            invalidate();
        }

        protected void onUnfocus() {
            super.onUnfocus();
            invalidate();
        }

        protected boolean keyDown(int keycode, int time) {
            char c = KeypadUtil.getKeyChar(keycode,
                    KeypadUtil.MODE_UI_CURRENT_LOCALE);
            if (c == '\n') {
                onClick();
            } else if (keycode == 13) {
                onClick();
            }
            return super.keyDown(keycode, time);
        }

        protected boolean navigationClick(int status, int time) {
            onClick();
            return true;
        }

        protected abstract void onClick();
    }
}
于 2012-08-03T12:46:08.437 回答
0

Screen1.java

    package com.app;

        import net.rim.device.api.system.Application;
        import net.rim.device.api.system.Display;
        import net.rim.device.api.ui.UiApplication;
        import net.rim.device.api.ui.component.ButtonField;
        import net.rim.device.api.ui.container.MainScreen;
        import net.rim.device.api.ui.container.VerticalFieldManager;

        public class Screen1 extends MainScreen {
            private VerticalFieldManager mainManager;
            private NavigationMenuBar tabBar;
        private static Screen1 ref= null;

    public static Screen1 getInstance(){
        if(ref==null){
            ref = new Screen1();
        }
        return ref;
    }
            public Screen1() {
                tabBar = new NavigationMenuBar() {

                    public void onNavigationClick(int selection) {
                        if (NavigationMenuBar.TAB1 == selection) {

                        } else if (NavigationMenuBar.TAB2 == selection) {
                            // Push Screen Which is releted to second tab
                            synchronized (Application.getEventLock()) {
                                Screen2.getInstance().setSelectedTab(NavigationMenuBar.TAB2);
                        UiApplication.getUiApplication().pushScreen(
                                Screen2.getInstance());
                            }
                        }
                    }
                };
                tabBar.selectTab(NavigationMenuBar.TAB1);
                mainManager = new VerticalFieldManager() {
                    protected void sublayout(int maxWidth, int maxHeight) {
                        super.sublayout(maxWidth, maxHeight);
                        setExtent(getPreferredWidth(), getPreferredHeight());
                    }

                    public int getPreferredWidth() {
                        return Display.getWidth();
                    }

                    public int getPreferredHeight() {
                        return Display.getHeight() - tabBar.getPreferredHeight();
                    }
                };
        //      setTitle("Screen one");
                mainManager.add(new ButtonField("Screen1"));

                add(mainManager);
                add(tabBar);
            }
public void setSelectedTab(int tabNumber) {
    tabBar.selectTab(tabNumber);
}
        }

屏幕2.java

 package com.app;

    import net.rim.device.api.system.Application;
    import net.rim.device.api.system.Display;
    import net.rim.device.api.ui.UiApplication;
    import net.rim.device.api.ui.component.ButtonField;
    import net.rim.device.api.ui.container.MainScreen;
    import net.rim.device.api.ui.container.VerticalFieldManager;

    public class Screen2 extends MainScreen {
        private VerticalFieldManager mainManager;
        private NavigationMenuBar tabBar;
    private static Screen2 ref= null;

    public static Screen2 getInstance(){
        if(ref==null){
            ref = new Screen2();
        }
        return ref;
    }
        public Screen2() {
            tabBar = new NavigationMenuBar() {

                public void onNavigationClick(int selection) {
                    if (NavigationMenuBar.TAB1 == selection) {
                        // Push Screen Which is releted to first tab
                        synchronized (Application.getEventLock()) {
                            Screen1.getInstance().setSelectedTab(NavigationMenuBar.TAB1);
                        UiApplication.getUiApplication().pushScreen(
                                Screen1.getInstance());
                        }
                    } else if (NavigationMenuBar.TAB2 == selection) {

                    }
                }
            };
            tabBar.selectTab(NavigationMenuBar.TAB2);
            mainManager = new VerticalFieldManager() {
                protected void sublayout(int maxWidth, int maxHeight) {
                    super.sublayout(maxWidth, maxHeight);
                    setExtent(getPreferredWidth(), getPreferredHeight());
                }

                public int getPreferredWidth() {
                    return Display.getWidth();
                }

                public int getPreferredHeight() {
                    return Display.getHeight() - tabBar.getPreferredHeight();
                }
            };
    //      setTitle("Screen two");
            mainManager.add(new ButtonField("Screen2"));
            add(mainManager);
            add(tabBar);
        }
public void setSelectedTab(int tabNumber) {
    tabBar.selectTab(tabNumber);
}
    }

请在 NAvigationMenuScreen 中评论这两行

tab1.setFocus();

tab2.setFocus();

于 2012-08-07T08:43:44.163 回答