【问题标题】:Blackberry scrolling doesn't redraw fields黑莓滚动不会重绘字段
【发布时间】:2013-12-03 19:45:04
【问题描述】:

我现在有一个很奇怪的问题。

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

我有一个屏幕 (NO_VERTICAL_SCROLL),标题栏是经理。在此之下,我有一个带有标签字段的垂直字段管理器 (VERTICAL_SCROLL)。当我滚动 vfm 时,已经可见的一两行标签字段被重新绘制。我向下滚动到的部分完全没有绘制任何内容。

我尝试了 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);
        }
    }
}

提前感谢您的任何建议

【问题讨论】:

  • 如果没有看到实际代码,我们无法告诉您代码出了什么问题。请编辑问题以粘贴到重要部分。谢谢。
  • 我们可以查看未正确绘制的字段的绘制方法吗?
  • 嗨,彼得,我设法找到了问题。但无法将此标记为已回答:/。非常感谢您的努力。
  • @Kevin,我认为接受您自己的答案需要等待一段时间,但如果您发布的答案确实是解决方案,最好接受它,以便以后阅读本文的人受益。所以,我明天再试试。谢谢。
  • 同意,我昨天试过了,但有 2 天的等待期。

标签: blackberry scroll redraw


【解决方案1】:

我认为除了在不查看代码的情况下猜测您的问题之外,别无他法。但无论您的问题是什么,我相信这是基于对如何在屏幕中使用管理器的误解。因此,我建议您查看以下文章以提高您在该领域的知识,并希望自己解决问题:

从这里开始: UI Introduction 这提供了经理和字段周围的背景。

然后阅读这篇文章: MainScreen Explained

我怀疑通过阅读这篇文章,您可能能够丢弃您的“标题栏”并使用 setTitle() 或 setBanner() 来提供此功能。

我希望这能解决您的问题。

其他几点:

在我所有多年的 BB 编程中,我从来没有使用过 doPaint() 来获得我想要的东西。我想不出这实际上会有所帮助的情况。因此,如果您认为需要它,请尝试使用 invalidate() 代替。

我在更改字段时使用了 invalidate(),这将更改其屏幕外观(但不会更改其大小)。我在滚动更改侦听器中使用了它。但这是不得已而为之的方法。

请记住,LabelFields 是不可聚焦的,因此在 6 之前的操作系统中,这使得它们无法滚动。

【讨论】:

  • 嗨,彼得,感谢您的回复。我不能使用 setTitle(),因为我已经在使用它来显示时钟/电池/网络/等。我确实在 doPaint() 之前尝试过 invalidate(),但都没有奏效。我的目标是 OS6 和 7。
  • 您可以使用 setBanner() 和 setTitle()。所以屏幕顶部有两个非滚动区域。
【解决方案2】:

发现问题。在标签字段上,有一个setExtent(getPreferredWidth(), getPreferredHeight()); 正在减小要重绘的区域的大小。非常愚蠢的错误。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多