要切换 LabelField 的颜色,我们可以检查它是否在它的 paint() 方法中被选中。但即便如此,我们也必须重新绘制 ListField 中的每一行。这就是问题所在:每次更改 ListField 的行选择时,只有两次调用 ListFieldCallback.drawRow() 方法 - 第一次用于前一个选定行(仍处于选定状态),第二次用于新选定行(已处于选定状态) ...
我试图保存以前选择的行索引并在每次调用 drawRow() 时重新绘制它,但由于某种原因,当时没有触发 LabelField.paint() 方法。
所以我提出了一个简单但丑陋的解决方案:调度 ListField.invalidate() TimerTask。100 毫秒的周期就足够了,也不会影响性能。
Jason Emerick 的代码我被用作扩展 ListField 的指南。
class LabelListField extends ListField implements ListFieldCallback {
private Vector mValues;
private Vector mRows;
public LabelListField(Vector values) {
super(0);
setRowHeight(70);
setCallback(this);
mValues = values;
fillListWithValues(values);
scheduleInvalidate();
}
private void scheduleInvalidate() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
invalidate();
}
}, 0, 100);
}
private void fillListWithValues(Vector values) {
mRows = new Vector();
for (int i = 0; i < values.size(); i++) {
TableRowManager row = new TableRowManager();
String title = "Item# " + String.valueOf(i + 1);
LabelField titleLabel = new LabelField(title);
titleLabel.setFont(Font.getDefault().derive(Font.BOLD));
row.add(titleLabel);
String value = (String) values.elementAt(i);
ListLabel valueLabel = new ListLabel(this, i, value);
valueLabel.setFont(Font.getDefault().derive(Font.ITALIC));
row.add(valueLabel);
mRows.addElement(row);
}
setSize(mRows.size());
}
private class TableRowManager extends Manager {
public TableRowManager() {
super(0);
}
public void drawRow(Graphics g, int x, int y,
int width, int height) {
layout(width, height);
setPosition(x, y);
g.pushRegion(getExtent());
paintChild(g, getField(0));
paintChild(g, getField(1));
g.popContext();
}
protected void sublayout(int width, int height) {
int fontHeight = Font.getDefault().getHeight();
int preferredWidth = getPreferredWidth();
Field field = getField(0);
layoutChild(field, preferredWidth - 5, fontHeight + 1);
setPositionChild(field, 5, 3);
field = getField(1);
layoutChild(field, preferredWidth - 5, fontHeight + 1);
setPositionChild(field, 5, fontHeight + 6);
setExtent(preferredWidth, getPreferredHeight());
}
public int getPreferredWidth() {
return Display.getWidth();
}
public int getPreferredHeight() {
return getRowHeight();
}
}
public void drawListRow(ListField listField, Graphics g,
int index, int y, int width) {
LabelListField list = (LabelListField) listField;
TableRowManager rowManager = (TableRowManager) list.mRows
.elementAt(index);
rowManager.drawRow(g, 0, y, width, list.getRowHeight());
}
public Object get(ListField list, int index) {
return mValues.elementAt(index);
}
public int indexOfList(ListField list, String prefix, int start) {
for (int x = start; x < mValues.size(); ++x) {
String value = (String) mValues.elementAt(x);
if (value.startsWith(prefix)) {
return x;
}
}
return -1;
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
class ListLabel extends LabelField {
int mIndex = -1;
public ListLabel(LabelListField list, int index, String text) {
super(text);
mIndex = index;
}
protected void paint(Graphics graphics) {
if (getSelectedIndex() == mIndex)
graphics.setColor(Color.RED);
else
graphics.setColor(Color.BLUE);
super.paint(graphics);
}
}
}