尝试为 BlackBerry 6/7 制作一个简单的数字点击器控件,如下所示:
从本质上讲,它只是一个文本字段和两个按钮,并带有一个 Manager 将它们隔开。
我知道不支持的附加 TableManager,但它不支持列扫描。而且,我发现使用深度嵌套的管理器的概念......令人不安。
而且,这会出现多次,所以我想要一个简单的、可重用的组件。
因此,我构建了一个简单的管理器来包含这三个组件,甚至允许您出于风格原因提供自己的文本字段或按钮。代码附在下面。显然比它需要的更漂亮,但工作都是在子布局中完成的。
实际发生的是 3 个组件中的每一个的右上角都出现在正确的位置,但是 3 个组件被“收缩包装”到显示其内容所需的最小尺寸,忽略了请求的 USE_ALL_WIDTH 和 USE_ALL_HEIGHT。这可能是一个小问题,但我怎样才能让这些组件真正使用所有宽度和使用所有高度?我在 USE_ALL_* 上尝试了几种变体,但还没有找到获胜的变体。当然,任何其他改进也将受到欢迎。
谢谢。
package layout;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.EditField;
/**
* XXX BROKEN DO NOT USE YET - layout fail, components get shrink-wrapped.
*
* NumberClicker Makes a layout with three components, like this:
* <pre>
* +-------------------+ +-------------------+
* | | | + |
* | 3 | |-------------------|
* | | |-------------------|
* | | | - |
* |-------------------| |-------------------|
* </pre>
* Note that by default, the buttons are set to increment and decrement the number in the textfield!
* @author Ian Darwin
*/
public class NumberClicker extends Manager {
private static final long SUBCOMPONENT_STYLE = Field.USE_ALL_HEIGHT | Field.USE_ALL_WIDTH;
private static final long MANAGER_STYLE = Field.FIELD_HCENTER | Field.FIELD_VCENTER;
final XYEdges MARGINS = new XYEdges(10,10,10,10);
EditField number = new EditField(SUBCOMPONENT_STYLE);
ButtonField plus = new ButtonField("+", SUBCOMPONENT_STYLE);
ButtonField minus = new ButtonField("-", SUBCOMPONENT_STYLE);
public NumberClicker() {
this(MANAGER_STYLE);
}
public NumberClicker(long style)
{
this(null, null, null, style);
}
/** Constructor allows you to provide your own three fields */
public NumberClicker(EditField number, ButtonField plus, ButtonField minus) {
this(number, plus, minus, MANAGER_STYLE);
}
/** Constructor allows you to provide your own three fields ANd override style.
* If any of the fields is null, the default value is used.
*/
public NumberClicker(EditField number, ButtonField plus, ButtonField minus, long style) {
super(style);
if (number != null) {
this.number = number;
} else {
this.number.setMargin(MARGINS); // set margins on our default, constructed above.
}
setValue(1);
add(this.number); // Nulls allowed, so must be careful to use "this." throughout this method.
if (plus != null) {
this.plus = plus;
} else {
this.plus.setMargin(MARGINS);
}
add(this.plus);
if (minus != null) {
this.minus = minus;
} else {
this.minus.setMargin(MARGINS);
}
add(this.minus);
this.plus.setRunnable(new Runnable() {
public void run() {
increment();
}
});
this.minus.setRunnable(new Runnable() {
public void run() {
decrement();
}
});
}
public void increment() {
number.setText(Integer.toString(Integer.parseInt(number.getText().trim()) + 1));
}
public void decrement() {
number.setText(Integer.toString(Integer.parseInt(number.getText().trim()) - 1));
}
/** Return the integer value of the clicker. Do not call if you are re-using this as a three-component layout manager! */
public int getValue() {
return Integer.parseInt(number.getText().trim());
}
public void setValue(int value) {
number.setText(Integer.toString(value));
}
/**
* Compute sizes and positions of subfields.
*
* Required by Manager
*/
public void sublayout(int width, int height) {
int layoutWidth = width;
int layoutHeight = Math.min(height, Display.getHeight()); // no scrolling here
System.err.println("Display:" + Display.getWidth() + "x" + Display.getHeight());
int halfX = layoutWidth / 2;
int halfY = layoutHeight / 2;
System.err.println("sublayout:" + width + "," + height + "; " + halfX + "," + halfY);
int numberWidth = halfX - number.getMarginLeft() - number.getMarginRight();
int numberHeight = layoutHeight - number.getMarginTop() - number.getMarginBottom();
layoutChild(number, numberWidth, numberHeight);
setPositionChild(number, 0 + number.getMarginLeft(), 0 + number.getMarginTop());
System.err.println(number + " " + numberWidth + "," + numberHeight + " " +number.getMarginLeft());
int plusWidth = halfX - plus.getMarginLeft() - plus.getMarginRight();
int plusHeight = halfY - plus.getMarginTop() - plus.getMarginBottom();
layoutChild(plus, plusWidth, plusHeight);
setPositionChild( plus, halfX + plus.getMarginLeft(), plus.getMarginTop());
int minusWidth = halfX - minus.getMarginLeft() - minus.getMarginRight();
int minusHeight = halfY - minus.getMarginTop() - minus.getMarginBottom();
layoutChild(minus, minusWidth, minusHeight);
// Use plus.getMarginHeight() for better alignment.
setPositionChild( minus, halfX + plus.getMarginLeft(), halfY + minus.getMarginTop() );
//setVirtualExtent(layoutWidth, height);
setExtent(layoutWidth, height);
}
public EditField getNumberField() {
return number;
}
public void setNumberField(EditField number) {
this.number = number;
}
public ButtonField getPlusField() {
return plus;
}
public void setPlusField(ButtonField plus) {
this.plus = plus;
}
public Field getMinusField() {
return minus;
}
public void setMinusField(ButtonField minus) {
this.minus = minus;
}
}