取消在布局管理器中滚动

时间:2009-09-04 13:48:32

标签: user-interface blackberry layout rim-4.2

我无法找到以下问题的解决方案。我有自定义列表字段,它重叠其布局管理器的边界。列表字段使用管理器中的导航事件来突出显示当前选定的具有特殊颜色的行。布局管理器配置为支持滚动。当我向下滚动拨轮时,布局管理器调用滚动,然后将导航事件传递给其子列表字段。它导致滚动不正确,因为管理器将整个列表向下滚动到顶部隐藏列表行,包括所选行。

我想要的是忽略滚动,而当前选择的列表行仍然可见,否则使用它。

我正在使用JDE 4.2.1

2 个答案:

答案 0 :(得分: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();
 }
}

如果我们想以这种方式在上下字段中对齐此列表: ListField with scroll 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上测试

答案 1 :(得分:0)

所有这些都是帮助我的解决方案。通过以特定的方式覆盖moveFocus,我设法修改了布局管理器中滚动的默认行为 - 它跳过列表字段的第一项,使它们保持在最顶层。

public int moveFocus(int amount, int status, int time) {
    invalidate(getSelectedIndex());

    int unused = super.moveFocus(amount, status, time);
    return Math.abs(unused) + 1;
}