0

選択した行のフォーカスを適切に描画するのに助けが必要です。現在、カテゴリの最初の項目を選択すると、区切り行も強調表示されます。では、選択した行のみがフォーカス/ハイライトされるようにカスタム フォーカス描画を実装するにはどうすればよいでしょうか?

ここから投稿されたソースコードを使用しています: Blackberry Tablemodel gets messed up when scrolling

RIM および JRE 7.0.0 の Eclipse IDE を使用しています。

public class ProductsScreen extends MainScreen
{
private TableModel _tableModel;

private static final int ROW_HEIGHT = 40;

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

    DBManager dbman = DBManager.getInstance();
    AllProductByCategory[] products = null;

    try {
            products = dbman.getProducts(mc.getID().intValue());
    } catch (DatabaseException e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    setTitle(mc.getName());

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

    if(products != null)
    {
        for(int i = 0; i < products.length; i++)
        {
            ViewableData[] data = products[i].getData().getViewableData();
            for(int j = 0; j < data.length; j++)
            {
                _tableModel.addRow(new Object[] {products[i].getCategoryName(), data[j].getTitle2()});
            }
        }
    }

    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);
    final TableController tableController = new TableController(_tableModel, tableView);

    tableController.setFocusPolicy(TableController.ROW_FOCUS);

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

    tableView.setController(tableController);

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

          Field[] fields = new Field[3];
          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 HeaderField((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 | Field.USE_ALL_HEIGHT | DrawStyle.ELLIPSIS);

          fields[2] = new BitmapField(Bitmap.getBitmapResource("img/bullet_arrow_right.png"));

          return fields;
       }
    };

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

    tableView.setDataTemplate(dataTemplate);

    add(tableView);
}
}

解決策: 次のアプローチで、自分で問題を解決できました。オーバーライドされた LabelField をヘッダーフィールドとして追加しただけで、そのフォーカス描画を実装していませんでした。したがって、「サブフィールド」のみがフォーカスを取得します。

別の方法で実装する人もいるかもしれませんが(ネイトからの回答を見てください)、私にとってはうまくいきました。

4

1 に答える 1

1

そのため、新しいコードサンプルを完全に統合する時間がありませんでした。このサンプルには、私が持っていないデータモデルコードがあり、のDataTemplate が追加されているようですBitmapField。うまくいけば、あなたは私がそれらの変更を再統合するために持っているものを適応させることができます。

これを行うには複数の方法があると確信しており、この方法が最高のパフォーマンスであるとは主張していません。ただし、その真下の行がフォーカスされているときにセパレータ行が強調表示されることなく、期待どおりにフォーカスが描画されているように見えます。

私がしたことは、複数の領域を使用するという概念を放棄し、データテンプレートを1行1列にすることでした。必要に応じて、1行2列にすることができます。ここで、表示しない列はですBitmapField

しかし、私がしたことは、VerticalFieldManager新しい各グループ/カテゴリの最初の行にを配置することでした。次にVerticalFieldManager、区切り文字/ヘッダー行、区切り文字フィールド(水平線のみ)、そして実際の製品行が含まれていました。行がグループ/カテゴリの最初ではない場合、 3つのオブジェクトが含まれているのでFieldはなく、単純なを返します。VerticalFieldManagerField

次に、TableControllerフォーカスポリシーをFIELD_FOCUSではなくに変更しましたROW_FOCUSVerticalFieldManagerこれにより、新しいグループ/カテゴリの最初の行にいるときに、フォーカスを取得できます。ただし、そのマネージャー内では、実際の製品行のみがフォーカス可能です。区切り行はフォーカスできないため、フォーカスを持って描画されません。

変更されたコードは次のとおりです。残りは私があなたに与えた前のサンプルと同じです:

  _tableController.setFocusPolicy(TableController.FIELD_FOCUS);
  _tableView.setController(_tableController);

  DataTemplate dataTemplate = new DataTemplate(_tableView, 1, 1)   // 1 row now!
  {         
     public Field[] getDataFields(int modelRowIndex)
     {
        final Object[] data = (Object[]) _tableModel.getRow(modelRowIndex);

        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) {               
           LabelField header = new LabelField((String)data[0], Field.USE_ALL_WIDTH | Field.NON_FOCUSABLE);
           SeparatorField line = new SeparatorField(Field.USE_ALL_WIDTH) {
              public void paint(Graphics g) {
                 g.setColor(Color.BLACK);
                 super.paint(g);
              }
           };
           LabelField productRow = new LabelField((String)data[1], 
                 Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);
           VerticalFieldManager manager = new VerticalFieldManager(Field.USE_ALL_WIDTH | Field.FOCUSABLE | 
                 Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR);
           manager.add(header);
           manager.add(line);
           manager.add(productRow);
           return new Field[] { manager };
        } else {
           return new Field[] { new LabelField((String)data[1], 
                 Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER) };
        }            
     }
  };

  // create just one region, with one row and one full-width column
  dataTemplate.createRegion(new XYRect(0, 0, 1, 1), _style);    // may be a product row, or a product row + separator
  dataTemplate.setColumnProperties(0, new TemplateColumnProperties(100, TemplateColumnProperties.PERCENTAGE_WIDTH));
  dataTemplate.setRowProperties(0, new TemplateRowProperties(2 * ROW_HEIGHT));       // max height if row + separator

  _tableView.setDataTemplate(dataTemplate);
  dataTemplate.useFixedHeight(false);

ページの一番下までスクロールすると少しおかしいですが、VerticalFieldManagerリストのように機能する前にサブクラスを作成したことは間違いありません。カスタムのスクロール処理が必要でした...明日時間があれば、に追加してみます。

ただし、一度に1ステップずつ...

于 2012-07-25T07:57:34.793 に答える