滚动时,Blackberry Tablemodel搞砸了

时间:2012-06-25 12:09:48

标签: blackberry tableview tablemodel

我想实现一个按字母顺序排序的可滚动List。 作为参考,我使用随Eclipse IDE提供的Tree Screen示例。

我更改了datatemplate以满足我的需求,它就像一个魅力,直到你想要滚动。整个用户界面搞砸了,我不知道该怎么做。我正在使用JRE 7.1和Blackberry Simulator 9860 7.0(我也在真实设备上测试过它)。

有人知道这是一个已知问题还是我错过了什么?

package lifeApp;

import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.table.DataTemplate;
import net.rim.device.api.ui.component.table.RegionStyles;
import net.rim.device.api.ui.component.table.SortedTableModel;
import net.rim.device.api.ui.component.table.TableController;
import net.rim.device.api.ui.component.table.TableModel;
import net.rim.device.api.ui.component.table.TableView;
import net.rim.device.api.ui.component.table.TemplateColumnProperties;
import net.rim.device.api.ui.component.table.TemplateRowProperties;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.decor.Border;
import net.rim.device.api.ui.decor.BorderFactory;
import net.rim.device.api.util.StringComparator;

public class ProductsScreen extends MainScreen
{
private SortedTableModel _tableModel;

private static final int ROW_HEIGHT = 40;

public ProductsScreen()
{
    super(Manager.NO_VERTICAL_SCROLL | Manager.HORIZONTAL_SCROLL);

    setTitle("Alle Produkte A-Z");

    add(new LabelField("BlackBerry Devices", LabelField.FIELD_HCENTER));
    add(new SeparatorField());

    _tableModel = new SortedTableModel(StringComparator.getInstance(true), 0);

    _tableModel.addRow(new Object[] {"A", "Produkt1"});
    _tableModel.addRow(new Object[] {"b", "Produkt2"});
    _tableModel.addRow(new Object[] {"c", "Produkt3"});
    _tableModel.addRow(new Object[] {"c", "Produkt4"});
    _tableModel.addRow(new Object[] {"b", "Produkt5"});
    _tableModel.addRow(new Object[] {"c", "Produkt6"});
    _tableModel.addRow(new Object[] {"c", "Produkt7"});
    _tableModel.addRow(new Object[] {"r", "Produkt8"});
    _tableModel.addRow(new Object[] {"t", "Produkt9"});
    _tableModel.addRow(new Object[] {"c", "Produkt10"});
    _tableModel.addRow(new Object[] {"b", "Produkt11"});
    _tableModel.addRow(new Object[] {"u", "Produkt12"});
    _tableModel.addRow(new Object[] {"v", "Produkt13"});
    _tableModel.addRow(new Object[] {"t", "Produkt14"});
    _tableModel.addRow(new Object[] {"c", "Produkt15"});
    _tableModel.addRow(new Object[] {"b", "Produkt16"});
    _tableModel.addRow(new Object[] {"u", "Produkt17"});
    _tableModel.addRow(new Object[] {"v", "Produkt18"});

    RegionStyles style = new RegionStyles(BorderFactory.createSimpleBorder(new XYEdges(1, 1, 1, 1), Border.STYLE_SOLID), null, null,
        null, RegionStyles.ALIGN_LEFT, RegionStyles.ALIGN_TOP);

    TableView tableView = new TableView(_tableModel);
    TableController tableController = new TableController(_tableModel, tableView);

    tableController.setFocusPolicy(TableController.ROW_FOCUS);

    tableController.setCommand(new Command(new CommandHandler()
    {
        public void execute(ReadOnlyCommandMetadata metadata, Object context)
        {
            Dialog.alert("Command Executed");
        }           
    }));

    tableView.setController(tableController);

    DataTemplate dataTemplate = new DataTemplate(tableView, 1, 1)
    {
        /**
         * @see DataTemplate#getDataFields(int)
         */
        public Field[] getDataFields(int modelRowIndex)
        {
            final Object[] data = (Object[]) ((TableModel) getView().getModel()).getRow(modelRowIndex);

            Field[] fields = new Field[1];
            fields[0] = new LabelField((String)data[1], Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);

            return fields;
        }
    };

    dataTemplate.createRegion(new XYRect(0, 0, 1, 1), style);  
    dataTemplate.setColumnProperties(0, new TemplateColumnProperties(100, TemplateColumnProperties.PERCENTAGE_WIDTH));
    dataTemplate.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));

    tableView.setDataTemplate(dataTemplate);
    dataTemplate.useFixedHeight(true);

    add(tableView);
}
}

1 个答案:

答案 0 :(得分:1)

好吧,我加载了JDE 7.1 UI / TableAndListDemo 示例应用,并在JDE 9900上运行它。

该样本(未经我修改)表现出与您发布的代码完全相同的螺旋行为。

所以,不幸的是,我会说有一个错误,或者有关如何使用相对较新的SortedTableModel的有效示例尚未生成(我找不到更好的错误)。

值得注意:如果您删除排序,只需将SortedTableModel替换为TableModel,视觉损坏就会消失。当然,您将失去排序和分组的重要功能(表模型中的第0列)。

另一个选择是自己实现排序行为。对TableModel之外的数据进行排序是不可取的,但也不是太困难。然后,您可以向重复模式添加一个额外的行,作为当前显示单个字符(排序标准)的分隔符行的占位符。您还可以将数据模板更改为固定高度。

此外,在数据模板中,您将定义可以保存分隔符行的区域。该区域是否显示任何内容取决于要跟随的数据行是否与最后一行具有相同的单个字符。所以,这是代码的样子

  DataTemplate dataTemplate = new DataTemplate(tableView, 2, 1)    // 2 "rows", not 1
  {
     public Field[] getDataFields(int modelRowIndex)
     {
        final Object[] data = (Object[]) _tableModel.getRow(modelRowIndex);

        Field[] fields = new Field[2];
        String rowGroup = (String)data[0];
        // we're in a new group if this is the very first row, or if this row's
        //  data[0] value is different from the last row's data[0] value
        boolean isNewGroup = (modelRowIndex == 0) || 
              (rowGroup.compareTo((String) ((Object[])_tableModel.getRow(modelRowIndex - 1))[0]) != 0);
        if (isNewGroup) {
           // make a separator row
           fields[0] = new LabelField((String)data[0], 
                          Field.USE_ALL_WIDTH | Field.NON_FOCUSABLE);
        } else {
           // this is in the same group as the last product, so don't add anything here
           fields[0] = new NullField();
        }
        // now, add the actual product information
        fields[1] = new LabelField((String)data[1], 
                          Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);

        return fields;
     }
  };


  dataTemplate.createRegion(new XYRect(0, 0, 1, 1), style);    // group separator (maybe a null field)
  dataTemplate.createRegion(new XYRect(0, 1, 1, 1), style);    // actual rows with product information
  dataTemplate.setColumnProperties(0, new TemplateColumnProperties(100, TemplateColumnProperties.PERCENTAGE_WIDTH));
  dataTemplate.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));   // separator
  dataTemplate.setRowProperties(1, new TemplateRowProperties(ROW_HEIGHT));   // product data
  dataTemplate.useFixedHeight(false);

在上面的代码中,我选择使分隔符行与产品数据行具有相同的高度和样式。当然,如果你愿意,你可以改变它。

这仍然没有解决的一个问题是焦点绘图。当您突出显示分隔符行下的第一行时,它会将焦点绘制在产品行和其上方的分隔行上。

您可能需要实现一些自定义焦点绘图。我会把它留给下一个问题...不确定你是否想要走这条路。希望我错了,但它看起来像RIM库中的一个错误:(