列表视图与章节标题

时间:2012-02-10 00:22:54

标签: android listview optimization

我已经看到了很多关于如何在线列出视图添加字母部分标题的示例。例如:

section headers

我实现了以下功能 this website 。但是,我有大约8000个项目的列表。尝试加载此页面时,大约需要8秒,这显然太慢了。只需一个普通的AlphabetIndexer,它需要大约1.5秒(仍然很慢,但更好)。

有没有人对如何提高速度有任何想法?如果没有,还有其他更快的例子吗?

谢谢!

2 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分:0)

ListView适配器有一个可以覆盖的类,名为getViewType(int position)getViewTypeCount()

您将覆盖以允许Android知道您的适配器使用了多少种不同类型的视图。

在您的情况下,覆盖getViewTypeCount()以返回2,因为您将有两种类型的视图。一个标准视图和第二个标题视图。

您需要知道您将在哪个位置显示标题视图。完成后,您可以轻松地在getView(...)函数上返回您的观点。