2012-02-10 103 views
3

我已經看到了很多關於如何添加按字母順序排列的頁眉列表視圖的例子。例如:列表視圖和章節標題

section headers

我從 this website 實現的功能。但是,我有一個約8000件物品的清單。當試圖加載這個頁面大約需要8秒,這顯然太慢了。只需一個普通的AlphabetIndexer,大約需要1.5秒(仍然很慢,但好多了)。

有沒有人有關於如何加快這一點的任何想法?如果不是,還有其他比這更快的例子嗎?

謝謝!

+0

看一看這個,http://developer.android.com/resources/tutorials/views/hello-listview.html,我知道它不正是你想要的,因爲你不能使用通過字母快速滾動,但它似乎很輕,往往加載速度很快 – FabianCook 2012-02-10 00:26:18

+0

對於8000個項目1.5秒,你認爲這很慢? – Squonk 2012-02-10 00:35:24

+0

@SmartLemon謝謝,但快速滾動對這個列表來說非常重要。 – Nick 2012-02-10 00:41:25

回答

1

你究竟試圖加載頁面是什麼意思?如果您只是加載項目並且不做任何索引,需要多長時間? 8000個項目並不是很多需要迭代的東西。然而,它可能需要從磁盤或互聯網加載很多項目。您可能需要考慮顯示加載屏幕並在背景中讀取行中的數據。

你顯示的代碼看起來特別複雜,你試圖做的事情。以下是我用過的解決方案。你可以谷歌的SectionIndexer。在我的代碼中,itemManager基本上只是一個列表上的抽象,佔位符是空值,其他的一切都是包含行信息的數據結構。省略了一些代碼:

//based on http://twistbyte.com/tutorial/android-listview-with-fast-scroll-and-section-index 

private class ContactListAdapter extends BaseAdapter implements SectionIndexer { 
    final HashMap<String, Integer> alphaIndexer = new HashMap<String, Integer>(); 
    final HashMap<Integer, String> positionIndexer = new HashMap<Integer, String>(); 
    String[] sections; 

    public ContactListAdapter() { 
     setupHeaders(); 
    } 

    public void setupHeaders(){ 
     itemManager.clearPlaceholders(); 
     for (int i = 0; i < itemManager.size(); i++) { 
      String name = itemManager.get(i).displayName(); 
      String firstLetter = name.substring(0, 1); 
      if (!alphaIndexer.containsKey(firstLetter)) { 
       itemManager.putPlaceholder(i); 
       alphaIndexer.put(firstLetter, i); 
       positionIndexer.put(i, firstLetter); 
       ++i; 
      } 

     } 
     final Set<String> sectionLetters = alphaIndexer.keySet(); 
     final ArrayList<String> sectionList = new ArrayList<String>(sectionLetters); 
     Collections.sort(sectionList); 
     sections = new String[sectionList.size()]; 
     sectionList.toArray(sections); 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return itemManager.isPlaceholder(position) ? ViewType.HEADER.ordinal() : ViewType.CONTACT.ordinal(); 
    } 

    @Override 
    public int getViewTypeCount() { 
     return ViewType.values().length; 
    } 

    @Override 
    public int getPositionForSection(int section) { 
     return alphaIndexer.get(sections[section]); 
    } 

    @Override 
    public int getSectionForPosition(int position) { 
     return 1; 
    } 

    @Override 
    public Object[] getSections() { 
     return sections; 
    } 
+0

你能提供完整的代碼嗎? – 2012-04-23 18:21:19

+0

我不能,但填寫我省略的任何東西都不會有太大麻煩。特別是你遇到什麼困難? – 2012-04-23 18:38:36

+0

我很困惑itemManager.putPlaceholder(i); itemManager本身是從哪個派生而來的?同樣在getSectionForPosition你只需返回1. 反正,謝謝你的迴應。 – 2012-04-23 19:14:27

0

ListView適配器有一個類可以覆蓋,稱爲getViewType(int position)getViewTypeCount()

您可以重寫以允許Android知道您的適配器使用了多少種不同類型的視圖。

在你的情況下,覆蓋getViewTypeCount()返回2,因爲你將有兩種類型的視圖。一個是你的標準,二是你的標題視圖。

比你需要知道你將在什麼位置顯示你的標題視圖。一旦你這樣做,你可以輕鬆地返回你的意見getView(...)功能。

+0

這就是我提供的鏈接。但是,我認爲這是「知道你在什麼位置可以看到你的標題視圖」,這會降低速度。這是我正在研究如何加速的一部分,但我不知道從哪裏開始。 – Nick 2012-02-10 00:40:46

+0

我建議你在SQLite數據庫中緩存你的數據。在那裏你可以很容易和快速地排序並添加這些標題行。將數據庫數據放入適配器將會超快速且容易! – Jona 2012-02-10 14:36:41