1

アルファベット順にソートされたスクロール可能なリストを実装したいと思います。参考として、EclipseIDEに付属しているツリー画面のサンプルを使用しています。

ニーズに合わせてデータテンプレートを変更しました。スクロールするまでは魅力のように機能します。UI全体が台無しになり、どうしたらよいかわかりません。JRE7.1とBlackberrySimulator9860 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);
}
}
4

1 に答える 1

1

さて、JDE 7.1 UI/TableAndListDemoサンプル アプリをロードし、JDE 9900 で実行しました。

そのサンプル (私が変更していない) は、投稿したコードとまったく同じ厄介な動作を示します。

残念ながら、バグがあるか、比較的新しい を使用する有効な例がSortedTableModel作成されていません (より良い例は見つかりませんでした)。

:並べ替えを削除し、単純に に置き換えるSortedTableModelTableModel、視覚的な破損がなくなります。もちろん、並べ替えとグループ化 (テーブル モデルの列 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);

上記のコードでは、区切り行を製品データ行と同じ高さとスタイルにすることを選択しました。もちろん、必要に応じて変更することもできます。

これがまだ解決されていない問題の 1 つは、フォーカス描画の問題です。区切り行の下の最初の行を強調表示すると、製品行とその上の区切り行にフォーカスが移動します。

カスタム フォーカス描画を実装する必要がある場合があります。それは次の質問に譲ります。うまくいけば私は間違っていますが、RIMライブラリのバグのように見えます:(

于 2012-07-01T12:02:02.583 に答える