2009-08-27 4 views
1

Je suis en train de mettre en place un dialogue qui devrait ressembler à ceci:Blackberry - Taille personnalisée EditField

Remplissez les champs ci-dessous
_______________ likes ____________________

où les lignes « _ » sont les EditFields.

Je colle tous les champs dans un HorizontalFieldManager, que j'ajoute à la boîte de dialogue. Malheureusement, le premier EditField consomme tout l'espace sur la première ligne. J'ai essayé de surcharger la méthode getPreferredWidth() de l'EditField en créant ma propre classe en étendant BasicEditField, mais je n'ai pas réussi.

Sûrement il doit y avoir un moyen simple de forcer une certaine taille pour un champ d'édition. Qu'est-ce que je rate?

Répondre

5

Tout comme DaveJohnston dit:

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

Merci! Cet exemple rend définitivement les choses plus claires. – Eric

+0

De rien! –

4

Essayez le sous-classement HorizontalFieldManager et remplacer la méthode sublayout:

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

Dans cette méthode, vous devez appeler setPositionChild() et layoutChild() pour chaque composant que vous ajoutez afin que vous puissiez contrôler le positionnement et la taille de chacun.

Vous devez également remplacer la méthode de mise en page de chaque composant et appeler

setExtent(getPreferredWidth(), getPreferredHeight()); 

cela fera usage de votre mise en œuvre des méthodes getPreferred ... vous avez déjà écrit.

Espérons que cela aide.

0

Miser sur la solution de Max Gontar, cela devrait résoudre le problème général d'attribuer une largeur aux sous champs 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); 
    } 
} 

appellent seulement les surcharges du méthode add pour spécifier la largeur et l'espace de décalage avant le champ suivant. Bien que cela ne permet pas de supprimer/remplacer des champs.

Il est ennuyeux que RIM ne fournisse pas cette fonctionnalité dans la bibliothèque standard. HorizontalFieldManager devrait juste fonctionner de cette façon.