blackberry horizontalfieldmanager

blackberry - labelField.getWidth() devuelve 0? ¿Por qué pasó esto?



horizontalfieldmanager (3)

Un breve resumen de la publicación de Nate.

Cuando construye el administrador y agrega campos, no espere que se distribuya correctamente. El gerente no conoce el contexto, dónde se colocará. Por lo tanto, solo se llamará el método de disposición para el campo cuando agregue su administrador a la pantalla (cuando también se llame al diseño para el administrador). Y esto es correcto

Mueva el cálculo de su variable side al método de layout .

Si realmente necesita valor side antes de poner administrador en pantalla. Puede precalcularlo usando Field.getPrefferedWidth() que devuelve valores significativos para campos estándar ( getFont().getAdvance(text) para LabelField , probablemente también con bordes, compruebe usted mismo). Pero ten cuidado con estos valores.

Estoy trabajando en mi propio administrador personalizado, y lo he completado hasta el momento, pero establece Margaritas usando un porcentaje de la resolución de pantalla.

Así es como llamo a la siguiente clase:

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

Aquí está la clase [He marcado en un comentario donde devuelve 0 y donde devuelve 219. por favor dígame por qué sucede esto:

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

Aquí hay una foto para ser más claro:


Nota: cuando ejecuté su código, realmente no vi labelField_width en 0 . Inicializas el valor a 40 en el código que publicaste arriba. Por lo tanto, a veces lo veo configurado en 40 o 219 (en una pantalla panorámica de 360 ​​px).

Pero, el problema es que creo que está intentando acceder al valor de labelField_width demasiado pronto. El único lugar al que está asignado correctamente está en el método de layout() de su LabelField anónimo. El hecho de que declare e implemente el método layout() en línea con la creación de instancias, no significa que se LabelField cuando se LabelField . Esta es en realidad una de las razones por las que no me gustan las clases anónimas.

De todos modos, este código:

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

Primero LabelField la instancia de LabelField (dentro del constructor LabelIconCommandManager ). Como dije, eso no dispara el método layout() . La segunda línea de arriba ( add() ) activará su método reemplazado:

// Overrride this managers add function public void add(Field imageButton) {

que es donde ves el mal valor de labelField_width . Ese método se llama antes del layout() . Ese es el problema.

Dado que parece que solo usa ese ancho para establecer el margen del buttonManager , puede esperar un poco más para hacerlo. Si espera hasta que se LabelIconCommandManager sublayout() LabelIconCommandManager sublayout() , su LabelField tendrá su método layout() llamado, y labelField_width asignado correctamente:

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

Ese método está en la clase LabelIconCommandManager . Y luego, puede eliminar el otro lugar al que llama buttonManager.setMargin() .


Por favor revise el código a continuación. Es el gerente que tiene etiqueta y botones. Y pone la etiqueta en el lado izquierdo y los botones en la derecha.

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

}