2009-08-27 152 views
1

我试图把一个对话框应该像这样的:黑莓 - 自定义大小EditField中

填写以下领域
_______________喜欢____________________

其中“_”行是EditFields。

我将所有字段粘贴到Horizo​​ntalFieldManager中,我将其添加到对话框中。不幸的是,第一个EditField消耗了第一行的所有空间。我试图通过创建自己的扩展BasicEditField的类来覆盖EditField的getPreferredWidth()方法,但没有成功。

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

回答

5

就像DaveJohnston说:

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

谢谢!这个例子肯定会让事情更清楚。 – Eric 2009-09-08 13:15:00

+0

不客气! – 2009-09-10 11:29:46

4

尝试继承Horizo​​ntalFieldManager并重写sublayout方法:

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

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

你也应该覆盖各部件的布局方法,并调用

setExtent(getPreferredWidth(), getPreferredHeight()); 

这会让你的使用实现你已经写了getPreferred ...方法。

希望这会有所帮助。

0

大厦最大Gontar的解决方案,这应该解决再转Horizo​​ntalFieldManagers的字段分配宽度的一般问题:

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

只需调用的重载添加方法来指定宽度,以及下一个字段之前的偏移量空间。虽然这不允许删除/替换字段。

RIM在标准库中不提供此功能令人厌烦。 Horizo​​ntalFieldManager 只是这样工作。