2012-02-10 65 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