Um die Farbe von LabelField zu wechseln, können wir überprüfen, ob es in der paint() -Methode ausgewählt ist. Aber selbst dann müssen wir jede Zeile in ListField neu streichen. Und das ist das Problem: Jedes Mal, wenn die Zeilenauswahl von ListField geändert wird, gibt es nur zwei Aufrufe der ListFieldCallback.drawRow() -Methode - zuerst für die vorherige ausgewählte Zeile (noch im ausgewählten Zustand) und zweite für die neue ausgewählte Zeile (bereits im ausgewählten Zustand) ...
Ich habe versucht, zuvor ausgewählten Zeilenindex zu speichern und es bei jedem Aufruf von drawRow() neu zu zeichnen, aber aus irgendeinem Grund wurde LabelField.paint() -Methode nicht ausgelöst.
So komme ich mit einer einfachen, irgendwie hässlichen Lösung: Zeitplan ListField.invalidate() TimerTask. Der Zeitraum in 100 ms ist ausreichend und beeinträchtigt auch nicht die Leistung.
Jason Emerick's code I've been used as a guide to extended 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);
}
}
}