Ежевика - Нестандартный размер EditField - PullRequest
1 голос
/ 27 августа 2009

Я пытаюсь собрать диалог, который должен выглядеть следующим образом:

Заполните поля ниже
_______________ лайков ____________________

где строки "_" являются полями редактирования.

Я прикрепляю все поля в HorizontalFieldManager, который добавляю в диалог. К сожалению, первый EditField занимает все место в первой строке. Я попытался переопределить метод getPreferredWidth () класса EditField, создав собственный класс, расширяющий BasicEditField, но безуспешно.

Конечно, должен быть простой способ принудительно установить определенный размер для поля редактирования. Чего мне не хватает?

Ответы [ 3 ]

5 голосов
/ 30 августа 2009

Точно так же, как Дейв Джонстон сказал:

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));
    }
}
4 голосов
/ 27 августа 2009

Попробуйте создать подклассификатор HorizontalFieldManager и переопределить метод подслоя:

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

В этом методе вы должны вызывать setPositionChild () и layoutChild () для каждого добавляемого компонента, чтобы вы могли контролировать расположение и размер каждого из них.

Вы также должны переопределить метод компоновки каждого компонента и вызвать

setExtent(getPreferredWidth(), getPreferredHeight()); 

это будет использовать вашу реализацию методов getPreferred ..., которые вы уже написали.

Надеюсь, это поможет.

0 голосов
/ 19 марта 2010

Основываясь на решении Макса Гонтара, это должно решить общую проблему назначения ширины подполям HorizontalFieldManagers:

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 не предоставляет эту функциональность в стандартной библиотеке. HorizontalFieldManager должен просто работать таким образом.

...