代码之家  ›  专栏  ›  技术社区  ›  Eric

BlackBerry-自定义大小编辑字段

  •  1
  • Eric  · 技术社区  · 15 年前

    我正试图建立一个这样的对话:

    填写以下字段
    ________喜欢___________

    其中“u”行是编辑字段。

    我将所有字段粘贴到水平字段管理器中,并将其添加到对话框中。不幸的是,第一个editfield会占用第一行中的所有空间。我试图通过创建扩展basicEditField的类来重写EditField的getPreferredWidth()方法,但没有成功。

    当然,必须有一种简单的方法来强制编辑字段使用一定的大小。我错过了什么?

    3 回复  |  直到 9 年前
        1
  •  5
  •   Maksym Gontar    15 年前

    就像戴夫约翰斯顿说的:

    class LikesHFManager extends HorizontalFieldManager {
        EditField mEditFieldLeft;
        LabelField mLabelField;
        EditField mEditFieldRight;
        String STR_LIKES = "likes";
        int mLabelWidth = 0;
        int mEditWidth = 0;
        int mOffset = 4;
    
        public LikesHFManager() {
            mEditFieldLeft = new EditField();
            mLabelField = new LabelField(STR_LIKES);
            mEditFieldRight = new EditField();
    
            mLabelWidth = mLabelField.getFont().getAdvance(STR_LIKES);
            int screenWidth = Display.getWidth();
            mEditWidth = (screenWidth - mLabelWidth) >> 1;
            mEditWidth -= 2 * mOffset;
    
            // calculate max with of one character
            int chMaxWith = mEditFieldLeft.getFont().getAdvance("W");
            // calculate max count of characters in edit field
            int chMaxCnt = mEditWidth / chMaxWith;
    
            mEditFieldLeft.setMaxSize(chMaxCnt);
            mEditFieldRight.setMaxSize(chMaxCnt);
    
            add(mEditFieldLeft);
            add(mLabelField);
            add(mEditFieldRight);
        }
    
        protected void sublayout(int maxWidth, int maxHeight) {
    
            int x = 0;
            int y = 0;
    
            int editHeight = mEditFieldLeft.getPreferredHeight();
            int labelHeight = mLabelField.getPreferredHeight();
    
            setPositionChild(mEditFieldLeft, x, y);
            layoutChild(mEditFieldLeft, mEditWidth, editHeight);
            x += mEditWidth;
            x += mOffset;
    
            setPositionChild(mLabelField, x, y);
            layoutChild(mLabelField, mLabelWidth, labelHeight);
            x += mLabelWidth;
            x += mOffset;
    
            setPositionChild(mEditFieldRight, x, y);
            layoutChild(mEditFieldRight, mEditWidth, editHeight);
            x += mEditWidth;
    
            setExtent(x, Math.max(labelHeight, editHeight));
        }
    }
    
        2
  •  4
  •   Michael Donohue Jan Gressmann    13 年前

    尝试对HorizontalFieldManager进行子类化,并重写子布局方法:

    protected void sublayout(int maxWidth, int maxHeight) { }
    

    在这个方法中,您应该为要添加的每个组件调用setPositionChild()和layoutChild(),这样您就可以控制每个组件的位置和大小。

    还应重写每个组件的布局方法并调用

    setExtent(getPreferredWidth(), getPreferredHeight()); 
    

    这将使用getPreferred的实现…您已经编写的方法。

    希望这有帮助。

        3
  •  0
  •   JGWeissman    14 年前

    基于Max Gontar的解决方案,这应该解决水平场管理器子字段宽度分配的一般问题:

    import net.rim.device.api.ui.container.*;
    import net.rim.device.api.ui.*;
    
    public class FieldRowManager extends HorizontalFieldManager {
        public FieldRowManager(final long style)
        {
            super(style);
        }
        public FieldRowManager()
        {
            this(0);
        }
    
        private SubField FirstSubField = null;
        private SubField LastSubField = null;
        private static class SubField
        {
            public final Field Field;
            public final int Width;
            public final int Offset;
            private SubField Next;
            public SubField(final FieldRowManager container, final Field field, final int width, final int offset)
            {
                Field = field;
                Width = width;
                Offset = offset;
    
                if (container.LastSubField == null)
                {
                    container.FirstSubField = this;
                }
                else
                {
                    container.LastSubField.Next = this;
                }
                container.LastSubField = this;
            }
            public SubField getNext()
            {
                return Next;
            }
        }
    
        public void add(final Field field)
        {
            add(field, field.getPreferredWidth());
        }
        public void add(final Field field, final int width)
        {
            add(field, width, 0);
        }
        public void add(final Field field, final int width, final int offset)
        {
            new SubField(this, field, width, offset);
            super.add(field);
        }
    
        protected void sublayout(final int maxWidth, final int maxHeight)
        {
            int x = 0;
            int height = 0;
            SubField subField = FirstSubField;
            while (subField != null)
            {
                final Field field = subField.Field;
                final int fieldHeight = field.getPreferredHeight();
                this.setPositionChild(field, x, 0);
                this.layoutChild(field, subField.Width, fieldHeight);
                x += subField.Width+subField.Offset;
                if (fieldHeight > height)
                {
                    height = fieldHeight;
                }
    
                subField = subField.getNext();
            }
            this.setExtent(x, height);
        }
    }
    

    只需调用add方法的重载来指定宽度和下一个字段之前的偏移空间。但这不允许删除/替换字段。

    RIM没有在标准库中提供这种功能,这让人很不舒服。水平场管理器 应该 就这样工作。

    推荐文章