2012-06-25 63 views
1

我想實現一個按字母順序排序的可滾動列表。 作爲參考,我使用隨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

好了,我裝了JDE 7.1 UI/TableAndListDemo示例應用程序,並運行它在JDE 9900

那樣品(由我未修改)具有完全相同的扭曲行爲的您發佈的代碼。

所以,不幸的是,我會說沒有錯誤,或者如何使用相對較新的SortedTableModel的有效示例尚未產生(我找不到任何更好的)。

:如您刪除排序,並簡單地用TableModel取代SortedTableModel,視覺腐敗消失我。當然,你失去了排序和分組的重要功能(表格模型中的第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庫我的錯誤:(

+0

嗨@Nate感謝您的回覆,我已經與段試了一下你張貼,它的工作(與提到的突出問題:-))。如果能爲SortedTableModel提供解決方案,我會告訴你。 – Danscho

+1

@spycob,是的,如果你決定採用這種自己的分類方法,爲了解決bug(?),只需要用你使用的代碼發佈一個新問題,並且說你需要幫助正確繪製焦點,因此分隔符行也不會突出顯示。 – Nate

+0

我會那樣做的。感謝您的幫助。 – Danscho