在ListView中创建简单的字母滚动?

时间:2011-02-25 21:17:07

标签: android listview android-layout

我希望模仿最新音乐应用程序中的功能,即弹出的漂亮小光标,可让人快速滚动到他们正在寻找的艺术家/专辑/曲目:

"Super Scrolling" Regular Scrolling

是否有方法可以在Android SDK的ListView中启用此类功能?

6 个答案:

答案 0 :(得分:16)

让列表适配器实现SectionIndexer。音乐应用程序还利用AlphabetIndexer来完成一些繁重的工作。还可以在实际setFastScrollEnabled(true)上使用ListView来启用此功能。

编辑:如果您没有使用CursorAdapter,则无法使用AlphabetIndexer。您可以尝试查看实现here,看看如何使其适应ArrayAdapter。

答案 1 :(得分:4)

这是我正在使用的ArrayAdapter的子类。请注意,我传入的objects已按字母顺序排序,并Collections.sort(objects)

class SectionIndexingArrayAdapter<T> extends ArrayAdapter<T> implements
        SectionIndexer {

    HashMap<String, Integer> sectionsMap = new HashMap<String, Integer>();
    ArrayList<String> sectionsList = new ArrayList<String>();

    ArrayList<Integer> sectionForPosition = new ArrayList<Integer>();
    ArrayList<Integer> positionForSection = new ArrayList<Integer>();

    public SectionIndexingArrayAdapter(Context context, int textViewResourceId,
            List<T> objects) {
        super(context, textViewResourceId, objects);

        // Note that List<T> objects has already been sorted alphabetically
        // e.g. with Collections.sort(objects) **before** being passed to
        // this constructor.

        // Figure out what the sections should be (one section per unique
        // initial letter, to accommodate letters that might be missing,
        // or characters like ,)
        for (int i = 0; i < objects.size(); i++) {
            String objectString = objects.get(i).toString();
            if (objectString.length() > 0) {
                String firstLetter = objectString.substring(0, 1).toUpperCase();
                if (!sectionsMap.containsKey(firstLetter)) {
                    sectionsMap.put(firstLetter, sectionsMap.size());
                    sectionsList.add(firstLetter);
                }
            }
        }

        // Calculate the section for each position in the list.
        for (int i = 0; i < objects.size(); i++) {
            String objectString = objects.get(i).toString();
            if (objectString.length() > 0) {
                String firstLetter = objectString.substring(0, 1).toUpperCase();
                if (sectionsMap.containsKey(firstLetter)) {
                    sectionForPosition.add(sectionsMap.get(firstLetter));
                } else
                    sectionForPosition.add(0);
            } else
                sectionForPosition.add(0);
        }

        // Calculate the first position where each section begins.
        for (int i = 0; i < sectionsMap.size(); i++)
            positionForSection.add(0);
        for (int i = 0; i < sectionsMap.size(); i++) {
            for (int j = 0; j < objects.size(); j++) {
                Integer section = sectionForPosition.get(j);
                if (section == i) {
                    positionForSection.set(i, j);
                    break;
                }
            }
        }
    }

    // The interface methods.

    public int getPositionForSection(int section) {
        return positionForSection.get(section);
    }

    public int getSectionForPosition(int position) {
        return sectionForPosition.get(position);
    }

    public Object[] getSections() {
        return sectionsList.toArray();
    }
}

答案 2 :(得分:3)

答案 3 :(得分:2)

在anddev.org上我找到了这个教程:Alphabetic FastScroll ListView - similar to Contacts

它还包含一个简短的demo-video

希望它有所帮助!

答案 4 :(得分:2)

要收集列表视图中显示的项目的详细信息,您可以执行以下操作:

@Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {

            albumButton.setText(songs.get(firstVisibleItem).getAlbum());

        }

这不是更简单吗?在这里,'songs'是Song对象的arraylist。您甚至可以通过添加firstVisibleItem + visibleItemCount来获取最后一个可见项。我发现这种技术非常有用。那么你会得到每首歌的第一个字母。我假设你发布的音乐应用中包含字母的灰色框是一个各种对话框?

无论如何,希望这会有所帮助。我意识到我迟到了,但这是为了未来的人

答案 5 :(得分:1)

我找到了一个很棒的解决方案here ...用一个巨大的列表做得很好......很好,很快......没有加载时间。

@Override
public int getPositionForSection(int section)
{
    log.info("Get position for section");

    for (int i = 0; i < this.getCount(); i++)
    {
        if (this.getItem(i).length() > 0)
        {
            String item = this.getItem(i).toUpperCase();
            if (item.charAt(0) == sections.charAt(section))
            {
                return i;
            }
        }
    }
    return 0;
}

@Override
public int getSectionForPosition(int arg0)
{
    log.info("Get section");

    return 0;
}

@Override
public Object[] getSections()
{
    log.info("Get sections");

    String[] sectionsArr = new String[sections.length()];

    for (int i = 0; i < sections.length(); i++)
    {
        sectionsArr[i] = "" + sections.charAt(i);
    }
    return sectionsArr;
}