黑莓滚动不会重绘字段

时间:2013-12-03 08:16:57

标签: blackberry scroll redraw

目前我有一个非常奇怪的问题。

基本上,当我在屏幕中滚动时,字段不会完全或一致地重绘。

我有一个屏幕(NO_VERTICAL_SCROLL),管理员作为标题栏。下面我有一个带有labelfields的垂直字段管理器(VERTICAL_SCROLL)。当我滚动vfm一行或两行已经可见的labelfield时,重新绘制。我向下滚动的部分绝对没有画出来。

我尝试使用invalidate(),并在scrollchangelistener中调用doPaint,但实际上它更糟糕。它导致标题栏仅部分重绘。

在下面的代码中,我使用了自定义FontManagerDimenManagerImageResourceManager来返回取决于屏幕大小的值。我使用了自定义BitmapButtonFieldClickableLabel,以便在保持点击时更改字段的状态。

public class BaseScreen extends MainScreen implements StringsResource
{
    protected ResourceBundle resources;

    public BaseScreen(long style)
    {
        super(style);

        StandardTitleBar titlebar = new StandardTitleBar();
        titlebar.addSignalIndicator();
        titlebar.addClock();
        titlebar.addNotifications();

        setTitle(titlebar);

        resources = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
    }
}

public class TandCScreen extends BaseScreen
{
    final String copy_text1 = "long text here";
    final String copy_text2 = "even longer text here";

    ColoredLabelField label_title;
    ColoredLabelField label_subtitle;
    ColoredLabelField label1;
    ColoredLabelField label2;
    ClickableLabel label3;

    public TandCScreen()
    {
        super(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR);
        label_title = new ColoredLabelField(resources.getString(STRING_APP_NAME), Color.WHITE, DrawStyle.HCENTER | USE_ALL_WIDTH);
        label_title.setBackground(BackgroundFactory.createSolidBackground(0x60223b));
        label_subtitle = new ColoredLabelField(resources.getString(STRING_TANDC_TITLE), 0x58585b, DrawStyle.HCENTER | USE_ALL_WIDTH);

        label1 = new ColoredLabelField(copy_text1, 0x58585b, USE_ALL_WIDTH);
        label2 = new ColoredLabelField("", 0xa7a9ab, USE_ALL_WIDTH);

        label3 = new ClickableLabel("Read more...")
        {
            protected void unclick()
            {
                super.unclick();
                UiApplication.getUiApplication().invokeLater(new Runnable()
                {
                    public void run()
                    {
                        ColoredLabelField label = new ColoredLabelField(copy_text2, 0xa7a9ab, 0);
                        label.setFont(FontManager.body());
                        label.setMargin(0, 0, DimenManager.interField(), 0);
                        label2.getManager().replace(label2, label);
                        label3.getManager().delete(label3);
                    }
                });
            }
        };

        label_title.setFont(FontManager.subtitle());
        label_subtitle.setFont(FontManager.subtitle());
        label1.setFont(FontManager.body());
        label2.setFont(FontManager.body());
        label3.setFont(FontManager.body());

        BitmapButtonField button_accept = new BitmapButtonField(ImageResourceManager.buttonAccept(), ImageResourceManager.buttonAcceptHover(), FIELD_HCENTER)
        {
            protected void click()
            {
                super.click();
                setImage(ImageResourceManager.buttonAcceptSelected());
                setFocusImage(ImageResourceManager.buttonAcceptSelected());
            }

            protected void unclick()
            {
                super.unclick();
                PersistentStoreManager.setTandCAccepted(true);
                UiApplication.getUiApplication().pushScreen(new LoginScreen());
                close();
            }
        };

        BitmapButtonField button_decline = new BitmapButtonField(ImageResourceManager.buttonDecline(), ImageResourceManager.buttonDeclineHover(), FIELD_HCENTER)
        {
            protected void click()
            {
                super.click();
                setImage(ImageResourceManager.buttonDeclineSelected());
                setFocusImage(ImageResourceManager.buttonDeclineSelected());
            }

            protected void unclick()
            {
                super.unclick();
                close();
            }
        };

        int margin = (VariableManager.DISPLAY_WIDTH - button_accept.getPreferredWidth()) / 2;
        // calculate where to put ellipsis
        Font font = label2.getFont();
        int max_length = (VariableManager.DISPLAY_WIDTH - margin * 2) * 2;
        int i = copy_text2.length() - 1;
        while (font.getAdvance(copy_text2.substring(0, i)) + font.getAdvance("...") >= max_length)
            i--;

        label2.setText(copy_text2.substring(0, i).trim() + "...");

        VerticalFieldManager vfm = new VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
        vfm.add(new NullField());
        vfm.add(label_subtitle);
        vfm.add(new Seperator());
        vfm.add(label1);
        vfm.add(label2);
        vfm.add(label3);
        vfm.add(button_accept);
        vfm.add(button_decline);

        vfm.setMargin(0, margin, 0, margin);

        // paddings
        int padding = (DimenManager.header() - label_title.getPreferredHeight()) / 2;
        label_title.setPadding(padding, 0, padding, 0);
        label_subtitle.setPadding(DimenManager.interField(), 0, DimenManager.interField(), 0);
        label1.setMargin(DimenManager.interField(), 0, DimenManager.interField(), 0);
        label3.setMargin(DimenManager.interField(), 0, DimenManager.interField(), button_accept.getPreferredWidth() - label3.getPreferredWidth());
        button_decline.setMargin(DimenManager.interField(), 0, DimenManager.interButton(), 0);

        add(label_title);
        add(vfm);
    }

    protected boolean onSavePrompt()
    {
        return false;
    }

    protected void makeMenu(Menu menu, int instance)
    {
        if (instance == Menu.INSTANCE_CONTEXT)
        {
            ContextMenu contextMenu = ContextMenu.getInstance();
            contextMenu.setTarget(this);
            contextMenu.clear();
            this.makeContextMenu(contextMenu);
            menu.deleteAll();
            menu.add(contextMenu);
        }
        else
        {
            super.makeMenu(menu, instance);
        }
    }
    protected void makeContextMenu(ContextMenu contextMenu)
    {
    }

    /**
     * Clickable labelfield which changes color on down press, and fires action
     * on release. Action is canceled if touch moves outside field bounds.
     * 
     * @author kevin
     * 
     */
    private class ClickableLabel extends LabelField
    {
        private boolean canceled = true;
        private boolean consumed = false;
        protected boolean pressed = false;

        public ClickableLabel(String label)
        {
            super(label, LabelField.FOCUSABLE | USE_ALL_WIDTH);
            setFont(FontManager.body());
        }

        protected void paint(Graphics g)
        {
            // background
            if (pressed)
            {
                g.setColor(0x2C1721);
            }
            else if (isFocus())
            {
                g.setColor(0x993C6B);
            }
            else
            {
                g.setColor(0x60223B);
            }

            int padding_y = (getPreferredHeight() - getFont().getHeight()) / 2;
            int padding_x = getPaddingLeft();
            g.drawText(getText(), padding_x, padding_y);
        }

        public int getPreferredHeight()
        {
            return ImageResourceManager.highlight().getHeight();
        }

        protected void layout(int width, int height)
        {
            height = getPreferredHeight();
            super.layout(width, height);
            setExtent(width, height);
        }

        // --------- Highlight selected row ---------
        protected void onFocus(int direction)
        {
            super.onFocus(direction);
            invalidate();
        }

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

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

        /**
         * Called when trackpad pressed, or touchscreen touched
         */
        protected void click()
        {
            pressed = true;
            invalidate();
        }

        /**
         * Called when trackpad released, or touchscreen released
         */
        protected void unclick()
        {
            cancel();
        }

        protected void cancel()
        {
            pressed = false;
            invalidate();
        }

        protected boolean navigationClick(int status, int time)
        {
            if (status != 0)
            {
                if (consumed)
                {
                    consumed = false;
                }
                else
                {
                    click();
                }
            }
            return true;
        }

        protected boolean navigationUnclick(int status, int time)
        {
            if (status != 0)
            {
                if (consumed)
                    consumed = false;
                else
                    unclick();
            }
            return true;
        }

        protected boolean touchEvent(TouchEvent message)
        {
            int x = message.getX(1);
            int y = message.getY(1);
            if (x < 0 || y < 0 || x > getExtent().width || y > getExtent().height)
            {
                // Outside the field
                if (!canceled)
                {
                    cancel();
                }
                canceled = true;
                return false;
            }

            if (message.getEvent() == TouchEvent.UP)
            {

                if (canceled)
                    cancel();
                else
                    unclick();
                consumed = true;

                return true;
            }
            if (message.getEvent() == TouchEvent.DOWN)
            {
                click();
                consumed = true;
                canceled = false;

                return true;
            }

            return super.touchEvent(message);
        }
    }

    private class Seperator extends SeparatorField
    {
        protected void paint(Graphics graphics)
        {
            graphics.setColor(0xa7a9ab);
            super.paint(graphics);
        }
    }
}

提前感谢任何建议

2 个答案:

答案 0 :(得分:0)

我不认为可以做任何事情,只是在不查看代码的情况下猜测你的问题。但无论你遇到什么问题,我都相信它是基于对如何在屏幕中使用管理器的误解。因此,我建议您查看以下文章,以提高您在此领域的知识,并希望自己解决问题:

从这里开始: UI Introduction 这提供了围绕经理和领域的背景。

然后阅读这篇文章: MainScreen Explained

我怀疑阅读本文后,您可以放弃“标题栏”并使用setTitle()或setBanner()来提供此功能。

我希望这可以解决你的问题。

其他几点:

在我多年的BB编程中,我从未使用过doPaint()来绘制我想要的绘画方式。我想不出这种事实上会有所帮助的情况。因此,如果您认为需要它,请尝试使用invalidate()。

当我对Field进行更改时,我使用了invalidate(),这将改变其屏幕外观(但不是它的大小)。我在滚动更改侦听器中使用它。但这是一种万不得已的方法。

请记住,LabelFields不可调焦,因此在6之前的操作系统中,这使得它们成为滚动的问题。

答案 1 :(得分:0)

发现了这个问题。在labelfields上,有setExtent(getPreferredWidth(), getPreferredHeight());缩小了要重绘的区域的大小。非常愚蠢的错误。

感谢所有试图提供帮助的人。