Pregunta

Estoy tratando de armar un cuadro de diálogo que debería tener este aspecto:

Rellene los campos siguientes
_______________ le gusta ____________________

donde los "_" líneas son la EditFields.

Me estoy pegando todos los campos de un HorizontalFieldManager, que agrego al diálogo. Por desgracia, la primera EditField consume todo el espacio en la primera línea. He tratado de sustituir el método getPreferredWidth () de la EditField mediante la creación de mi propia clase que se extiende BasicEditField, pero no han tenido éxito.

Sin duda debe ser una forma sencilla para forzar un cierto tamaño de un campo de edición. ¿Qué me falta?

¿Fue útil?

Solución

Al igual que DaveJohnston dijo:

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));
    }
}

Otros consejos

Trate subclases HorizontalFieldManager y reemplazar el método sublayout:

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

En este método debe llamar setPositionChild () y layoutChild () para cada componente que está agregando para que pueda controlar la posición y el tamaño de cada uno.

También debe reemplazar el método de diseño de cada componente y llamar

setExtent(getPreferredWidth(), getPreferredHeight()); 

esto hará uso de su aplicación de la getPreferred ... métodos que ya ha escrito.

Espero que esto ayude.

Sobre la base de la solución de Max Gontar, esto debería resolver el problema general de asignación de ancho de sub campos de 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);
    }
}

Sólo tiene que llamar las sobrecargas del método add para especificar el ancho y el espacio de desplazamiento antes de que el siguiente campo. Aunque esto no permite borrar / reemplazar campos.

Es irritante que RIM no proporciona esta funcionalidad en la biblioteca estándar. HorizontalFieldManager debe acaba de trabajar de esta manera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top