Отмена прокрутки в менеджере макетов
Я не могу найти решение для следующей проблемы. У меня есть настраиваемое поле списка, которое перекрывает границы его менеджера по расположению. Поле списка потребляет события навигации от менеджера, чтобы выделить выбранную строку специальным цветом. Диспетчер макетов настроен для поддержки прокрутки. Когда я прокручиваю колесико вниз, менеджер компоновки запускает прокрутку, а затем передает событие навигации своему дочернему элементу, полю списка. Это приводит к неправильной прокрутке, потому что менеджер прокручивает весь список вниз до его нижних строк списка скрытия сверху, включая выбранную строку.
Я хочу игнорировать прокрутку, пока выбранная строка списка еще видна, и использовать ее в противном случае.
Я использую JDE 4.2.1
2 ответа
Все вот решение, которое помогло мне. Переопределив moveFocus таким специфическим способом, мне удалось изменить стандартное поведение прокрутки в менеджере компоновки - он пропускает первые элементы поля списка, позволяя им оставаться на вершине.
public int moveFocus(int amount, int status, int time) {
invalidate(getSelectedIndex());
int unused = super.moveFocus(amount, status, time);
return Math.abs(unused) + 1;
}
Допустим, у нас есть реализация ListField:
class LabelListField extends ListField implements ListFieldCallback {
private Vector mValues;
public LabelListField(Vector values) {
super(0);
setRowHeight(getFont().getHeight() + 10);
setCallback(this);
mValues = values;
setSize(mValues.size());
}
public void drawListRow(ListField listField, Graphics g, int index, int y,
int width) {
g.drawText((String) mValues.elementAt(index), 0, y);
}
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();
}
}
Если мы хотим выровнять этот список в верхнем и нижнем полях следующим образом: http://img6.imageshack.us/img6/7025/8800j.png
мы можем ограничить его высоту, используя собственный менеджер:
class ListManager extends HorizontalFieldManager {
ListField mListField;
public ListManager(ListField listField) {
super(VERTICAL_SCROLL | VERTICAL_SCROLLBAR);
mListField = listField;
add(mListField);
}
public int getPreferredHeight() {
int result = Display.getHeight();
Manager manager = getManager();
if (null != manager) {
for (int i = 0, count = manager.getFieldCount(); i < count; i++) {
if (manager.getField(i) != this)
result -= manager.getField(i).getPreferredHeight();
}
}
// size down to fit max rows without splitting
result = result - result % mListField.getRowHeight();
return result;
}
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(maxWidth, maxHeight);
setExtent(maxWidth, getPreferredHeight());
}
}
Теперь мы можем использовать это:
class Scr extends FullScreen implements FieldChangeListener {
LabelField mHeader;
ListManager mHFMList;
HorizontalFieldManager mHFMButton;
LabelListField mListField;
ButtonField mButton;
public Scr() {
super(DEFAULT_MENU | DEFAULT_CLOSE);
mHeader = new LabelField("List Field", FIELD_HCENTER);
add(mHeader);
Vector values = new Vector();
values.addElement("first");
values.addElement("second");
values.addElement("third");
values.addElement("fourth");
values.addElement("fifth");
values.addElement("sixth");
values.addElement("seventh");
values.addElement("eight");
mListField = new LabelListField(values);
mHFMList = new ListManager(mListField);
add(mHFMList);
mHFMButton = new HorizontalFieldManager(FIELD_HCENTER);
add(mHFMButton);
mButton = new ButtonField("Exit", ButtonField.CONSUME_CLICK);
mButton.setChangeListener(this);
mHFMButton.add(mButton);
}
public void fieldChanged(Field field, int context) {
if (mButton == field)
close();
}
}
Проверено на eJDE 4.2.1.17 8800