Pour changer de couleur de LabelField, nous pouvons vérifier s'il est sélectionné dans sa méthode paint(). Mais même alors, nous devrons repeindre chaque rangée dans ListField. Et c'est le problème: chaque fois que la sélection de ligne de ListField est modifiée, il n'y a que deux appels de la méthode ListFieldCallback.drawRow() - d'abord pour la ligne sélectionnée précédente (toujours dans l'état sélectionné) et ensuite pour la nouvelle ligne sélectionnée (déjà dans l'état sélectionné) ...
J'ai essayé de sauvegarder l'index de ligne sélectionné précédent et de le redessiner à chaque appel de drawRow(), mais pour une raison quelconque, la méthode LabelField.paint() n'a pas été déclenchée alors. Donc je viens avec une solution simple, en quelque sorte laide: schedule ListField.invalidate() TimerTask. Une période de 100 ms est suffisante et n'atteint pas les performances.
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);
}
}
}