如何在Android ListView的侧边显示字母排序

37
我看了很多有关制作ListView侧边字母表(如联系人列表)的教程,但它们似乎都使用ListActivity类和/或来自数据库的数据,而我只是使用ListView(没有特殊活动)和一个数据ArrayList。 有人知道我如何在我的ListView中实现那个联系人列表的字母滚动功能吗?
编辑后
我按照 这个教程 做,本以为最终可以解决问题,但还是出现了强制关闭。
class AlphabeticalAdapter extends ArrayAdapter<String> implements SectionIndexer
{
    private HashMap<String, Integer> alphaIndexer;
    private String[] sections;

    public AlphabeticalAdapter(Context c, int resource, List<String> data)
    {
        super(c, resource, data);
        for (int i = 0; i < data.size(); i++)
        {
            String s = data.get(i).substring(0, 1).toUpperCase();
            alphaIndexer.put(s, i);
        }

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

    }

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

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

    public Object[] getSections()
    {
        return sections;
    }
}

在LogCat中,它显示java.lang.RuntimeException: Unable to resume activity {(我制作的另一个应用程序包名) android.app.SuperNotCalledExcpetion。我认为这非常奇怪,因为我在我正在处理的应用程序中根本没有引用那个其他应用程序。我尝试卸载那个其他应用程序,仍然出现了强制关闭,但是我可以看到LogCat说了什么,因为它没有更新。

最终编辑

这是可工作的代码。很抱歉发布晚了大约9个月。

class AlphabeticalAdapter extends ArrayAdapter<String> implements SectionIndexer
{
    private HashMap<String, Integer> alphaIndexer;
    private String[] sections;

    public AlphabeticalAdapter(Context c, int resource, List<String> data)
    {
        super(c, resource, data);
        alphaIndexer = new HashMap<String, Integer>();
        for (int i = 0; i < data.size(); i++)
        {
            String s = data.get(i).substring(0, 1).toUpperCase();
            if (!alphaIndexer.containsKey(s))
                alphaIndexer.put(s, i);
        }

        Set<String> sectionLetters = alphaIndexer.keySet();
        ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
        Collections.sort(sectionList);
        sections = new String[sectionList.size()];
        for (int i = 0; i < sectionList.size(); i++)
            sections[i] = sectionList.get(i);   
    }

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

    public int getSectionForPosition(int position)
    {
        for ( int i = sections.length - 1; i >= 0; i-- ) {
            if ( position >= alphaIndexer.get( sections[ i ] ) ) {
                return i;
            }
        }
        return 0;
    }

    public Object[] getSections()
    {
        return sections;
    }
}

编辑:如果您想要在滚动时使您的滚动条出现在正确的位置,则getSectionForPosition非常重要。仅返回1(或0)表示您只是在第一(或第二)部分中滚动,这将导致滚动条的错误位置(大多数情况下超出屏幕)。添加的代码返回适当的部分,因此滚动条可以知道它实际上在哪里。

您为什么不想使用ListActivity?您能否提供所说的教程链接? - i_am_jorf
获取单词的第一个字母 - Pat Needham
我尝试了substring(0, 1),但仍然不起作用。 - Pat Needham
将 getSectionForPosition 更改为返回 0;这样在 ListView 底部滑动时会更加平滑。 - MobileMon
你能否请发一下完整的代码?我已经实现了,但是它对我来说不起作用。非常感谢。 - Muhammad Younas
2个回答

21

我忘记实例化 alphaIndexer。现在完美运行。

class AlphabeticalAdapter extends ArrayAdapter<String> implements SectionIndexer
{
    private HashMap<String, Integer> alphaIndexer;
    private String[] sections;

    public AlphabeticalAdapter(Context c, int resource, List<String> data)
    {
        super(c, resource, data);
        alphaIndexer = new HashMap<String, Integer>();
        for (int i = 0; i < data.size(); i++)
        {
            String s = data.get(i).substring(0, 1).toUpperCase();
            if (!alphaIndexer.containsKey(s))
                alphaIndexer.put(s, i);
        }

        Set<String> sectionLetters = alphaIndexer.keySet();
        ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
        Collections.sort(sectionList);
        sections = new String[sectionList.size()];
        for (int i = 0; i < sectionList.size(); i++)
            sections[i] = sectionList.get(i);   
    }

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

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

    public Object[] getSections()
    {
        return sections;
    }
}

@Pat:你好,如果你已经完成了最终的工作演示,请提供给我。谢谢。 - Shreyash Mahajan
1
@Pat 很好,很难找到一个适当的教程来讲解这个主题,但是这个直接就可以使用了。谢谢。 - Warpzit
你的手机/模拟器使用哪个版本的Android系统,你的目标版本又是哪个?这可能会产生影响。 - Pat Needham
@PatNeedham,我这里没有显示字母表...我们需要在我的ListView XML文件中添加什么吗?还是上面的内容已经足够让字母表显示出来了? - Zxxxxx
一个改进的方法是使用Collator:Collator coll = Collator.getInstance(); coll.setStrength(Collator.TERTIARY); Collections.sort(sectionList, coll); - Ahmet Noyan Kızıltan
显示剩余2条评论

3

我认为他们要求实际看到A、B、C等内容,类似于iPhone联系人列表界面。一种自定义滚动条小部件类型的东西。 - i_am_jorf
在滚动期间有一个区域和可见的对话框。并且ListView上设置了fastScrollEnabled为true。 - Harald Wilhelm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接