labelField.getWidth()返回0?为什么会这样?

时间:2012-07-31 19:27:48

标签: blackberry horizontalfieldmanager

我正在开发自己的自定义管理器,到目前为止我已经完成了它,但它使用一定百分比的屏幕分辨率设置了Margins。

以下是我如何调用以下类:

LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));

这是类[我在注释中标记它返回0并返回219.请告诉我为什么会发生这种情况:

public class LabelIconCommandManager extends HorizontalFieldManager implements  BCMSField
{
    LabelIconCommandManager me = this;
    EvenlySpacedHorizontalFieldManager buttonManager = new EvenlySpacedHorizontalFieldManager(0);
    LabelField labelField;
    int side = 0;
    int HPADDING = 3;
    int VPADDING = 4;
    int screenWidth = Display.getWidth();
    int labelField_width = 40;
    public LabelIconCommandManager()
    {
        this("", 0);
    }
    public LabelIconCommandManager(String label, long style)
    {
        super(USE_ALL_WIDTH| FOCUSABLE);
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
        this.setMargin(1,10,1,10);
        labelField = new LabelField(label,LabelField.ELLIPSIS)
        {
            public void layout(int width, int height)
            {
                // Done because otherwise ellipses dont work with labelfields
                super.layout((int)(screenWidth * 0.61), getHeight());
                setExtent((int)(screenWidth * 0.61), getHeight());
                labelField_width = labelField.getWidth();
                DisplayDialog.alert("labelField_width = " + labelField_width); // returns 219
            }
        };
        // Top Right Bottom Left
        labelField.setMargin(VPADDING, HPADDING, VPADDING, 0);
        // super because we want this horizontalfieldManager to add it
        super.add(labelField);
        super.add(buttonManager);
    }
    public void alternateConstructor(Attributes atts)
    {
        labelField = new LabelField(atts.getValue("label"), 0);
    }
    public void onFocus(int direction)
    {
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit_select.png" )));
        // uses the same color as listStyleButtonField selections
        this.setBackground(BackgroundFactory.createSolidBackground(0x186DEF));
        super.onFocus(direction);
    }
    //Invoked when a field loses the focus.
    public void onUnfocus()
    {
        //top, right,bottom,left
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
        this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GRAY, 0));
        super.onUnfocus();
        invalidate();
    }
    // Overrride this managers add function
    public void add(Field imageButton)
    {
        // Add a button to the evenly spaced manager
        buttonManager.add(imageButton);
        // Based on how many buttons there are, set the margin of where the manager holding the buttons start [offset from labelField]
        if(buttonManager.getFieldCount() == 1)
        {
            //side = (int)(screenWidth * 0.1388);
            side = screenWidth - labelField_width - 32 - 10 - 15;
            DisplayDialog.alert("Screen Width = " + screenWidth);
            DisplayDialog.alert("labelField_width2 = " + labelField_width); // returns 0
            DisplayDialog.alert("Side = " + side);
        }
        else side = (int)(screenWidth * 0.05);
        buttonManager.setMargin(0,0,0,side);
    }
    public int getLabelWidth()
    {
        return labelField_width;
    }
}  

这是一张更清晰的图片:

Snapshot

3 个答案:

答案 0 :(得分:2)

注意:当我运行您的代码时,我实际上并未将labelField_width设置为0。您在上面发布的代码中将值初始化为40。因此,我有时会将其设置为40或219(在360 px宽屏幕上)。

但问题是,我认为你过早地试图访问labelField_width的价值。正确分配的唯一位置是匿名layout()的{​​{1}}方法。仅仅因为您根据实例化声明并实现LabelField方法,并不意味着在创建layout()时调用它。这实际上是我不喜欢匿名课程的原因之一。

无论如何,这段代码:

LabelField

首先实例化LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0); licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK)); (在LabelField构造函数内)。正如我所说,会触发LabelIconCommandManager方法。上面的第二行(layout())将触发您重写的方法:

add()

您可以在其中看到// Overrride this managers add function public void add(Field imageButton) { 的错误值。该方法在labelField_width之前被调用。这就是问题所在。

由于看起来您只使用该宽度设置layout()页边距,因此您可以稍等一会儿。如果您等到调用buttonManager LabelIconCommandManager方法,则sublayout()已调用LabelField方法并正确分配layout()

labelField_width

该方法进入protected void sublayout(int maxWidth, int maxHeight) { // make sure to call superclass method first! super.sublayout(maxWidth, maxHeight); // now, we can reliably use the label width: side = screenWidth - labelField_width - 32 - 10 - 15; buttonManager.setMargin(0,0,0,side); } 类。然后,您可以移除您拨打LabelIconCommandManager的其他地方。

答案 1 :(得分:2)

Nate post的一些简短摘要。

构建经理并添加字段时,不要指望它会正确布局。经理不知道上下文 - 它将被放置在何处。 因此,只有当您将其经理添加到屏幕时才会调用字段的布局方法(当还会调用经理的布局时)。这是正确的。

side变量的计算方式移至layout方法。

如果在将经理放到屏幕之前确实需要side值。您可以使用Field.getPrefferedWidth()为标准字段返回有意义的值(getFont().getAdvance(text) LabelField,也可以使用边框请自行检查),从而预先计算它。但要小心这个值。

答案 2 :(得分:1)

请查看下面的代码。它的经理有标签和按钮。它将标签放在左侧,按钮放在右侧。

import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.decor.Border;

import java.util.Vector;

public class TabFieldManager extends Manager {

public TabFieldManager(long style) {
    super(style);
}

protected void sublayout(int width, int height) {
    LabelField label = null;

    Vector tabs = new Vector();
    int tabsWidth = 0;
    int tabHeight = 0;
    int tabPaddingTop = 0;
    int tabPaddingLeft = 0;

    for (int i=0; i < getFieldCount(); i++) {
        Field field = getField(i);
        if (field instanceof LabelField) {
            label = (LabelField) field;
        } else if (field instanceof ButtonField){
            tabs.addElement(field);

            layoutChild(field, width, height);

            int fieldwidth = field.getWidth() > 0 ? field.getWidth() : field.getPreferredWidth() ;
            tabsWidth += fieldwidth + getBorderAndPaddingWidth(field);

            int fieldHeight = field.getHeight() > 0 ? field.getHeight() : field.getPreferredHeight();
            if (fieldHeight > tabHeight) {
                tabHeight = getBorderAndPaddingHeight(field) + fieldHeight;
            }

            int fieldPaddingTop = field.getPaddingTop();
            if (fieldPaddingTop > tabPaddingTop) {
                tabPaddingTop = fieldPaddingTop;
            }

            int fieldPaddingLeft = field.getPaddingLeft();
            if (fieldPaddingLeft > tabPaddingLeft) {
                tabPaddingLeft = fieldPaddingLeft;
            }
        }
    }

    if (label != null) {
        layoutChild(label, width - tabsWidth, height);
        int y = tabHeight - label.getHeight() >> 1;
        setPositionChild(label, tabPaddingLeft , y);
    }
    for (int i = 0; i < tabs.size(); i++) {
        Field tabField = (Field) tabs.elementAt(i);
        setPositionChild(tabField, width - tabsWidth, getBorderAndPaddingHeight(tabField));
        tabsWidth -= tabField.getWidth() + getBorderAndPaddingWidth(tabField);
    }

    setExtent(width, tabHeight);
}

private int getBorderAndPaddingHeight( Field field ) {
    int height = field.getPaddingTop() + field.getPaddingBottom();
    Border border = field.getBorder();
    if( border != null ) {
        height += border.getTop() + border.getBottom();
    }

    return height;
}

private int getBorderAndPaddingWidth( Field field ){
    int width = field.getPaddingLeft() + field.getPaddingRight();
    Border border = field.getBorder();
    if( border != null ) {
        width += border.getLeft() + border.getRight();
    }
    return width;
}

protected int moveFocus(int amount, int status, int time) {
    if ((status & Field.STATUS_MOVE_FOCUS_VERTICALLY) == Field.STATUS_MOVE_FOCUS_VERTICALLY && amount > 0) {
        return amount;
    } else
        return super.moveFocus(amount, status, time);
}

protected int nextFocus(int amount, int axis) {
    if (amount > 0 && axis == Field.AXIS_VERTICAL)
        return -1;
    else
        return super.nextFocus(amount, axis);
}

}