2

私は独自のカスタム マネージャーに取り組んでおり、これまでのところ完成していますが、画面解像度のパーセンテージを使用して 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;
    }
}  

より明確にするための写真を次に示します。

スナップショット

4

3 に答える 3

2

注:labelField_widthコードを実行したとき、実際にはに設定されていることはわかりませんでした040上記で投稿したコードで値を初期化します。そのため、40または219(360ピクセルのワイドスクリーン上)に設定されているのを時々目にします。

labelField_widthしかし、問題は、あなたがあまりにも早くの価値にアクセスしようとしていると思うということです。適切に割り当てられる唯一の場所はlayout()、匿名のメソッドですLabelField。インスタンス化に沿ってメソッドを宣言して実装したからとlayout()いって、が作成されたときに呼び出されるわけではありませんLabelField。これが、私が匿名クラスを嫌う理由の1つです。

とにかく、このコード:

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

LabelField最初に(LabelIconCommandManagerコンストラクター内で)インスタンス化します。私が言ったように、それはメソッドをトリガーしません。layout()上記の2行目(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クラスに入ります。次に、呼び出した他の場所を削除できますbuttonManager.setMargin()

于 2012-08-01T01:17:44.713 に答える
2

ネイトの投稿からの簡単な要約。

manager を構築してフィールドを追加するとき、それが正しくレイアウトされるとは思わないでください。マネージャーは、コンテキスト (配置される場所) を知りません。したがって、フィールドのレイアウト メソッドは、管理者を画面に追加するときにのみ呼び出されます (管理者のレイアウトも呼び出される場合)。そして、これは正しいです。

side変数の計算をlayoutメソッドに移動します。

sideマネージャーを画面に表示する前に、本当に価値が必要な場合。Field.getPrefferedWidth()which を使用して、標準フィールドに意味のある値を返すことで事前に計算できます ( getFont().getAdvance(text)for LabelField、おそらく境界線も自分で確認してください)。ただし、この値には注意してください。

于 2012-08-01T06:23:53.320 に答える
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);
}

}

于 2012-08-01T14:37:42.760 に答える