How to show alphabetical letters on side of Android ListView
I've looked at a lot of tutorials for making a ListView have the alphabetical letters on the side (like the Contacts list), but they all seem to using a ListActivity class and/or data from a database while I'm just using a ListView (no special Activity) and an ArrayList of data. Does anyone know how I can implement that alphabetical-scroll feature in the Contacts list for my own ListView?
Edited Again
I followed this tutorial, which I thought would finally make it work, but I'm still getting a forced close.
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;
}
}
In the LogCat, it says java.lang.RuntimeException: Unable to resume activity {(package of another app I made) android.app.SuperNotCalledExcpetion
. I thought that was really weird because I don't reference that other app at all in the one I'm working with. I tried uninstalling that other app, still got the forced close, but I could see what the LogCat said because it didn't update.
Final Edit
Here is the working code. Sorry for posting it something like 9 months overdue.
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;
}
}
Edit : getSectionForPosition is important if you want your scroller appear in the right place while you are scrolling. Returning only 1 (or 0) tells that you are just scrolling in the first (or second) section which will result in scroller's wrong position (mostly goes out of screen). Added code returns the appropriate section so scroller can know where it actually is.
Solution 1:
I forgot to instantiate alphaIndexer
. Works perfectly now.
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;
}
}
Solution 2:
If I understand you correctly, you want to set fastScrollEnabled=true
and that will give you the little thumb scroller on the right. If you want to add a floating letter like the one in contacts, there is a great example in the APIDemos project in List9.java (http://www.devdaily.com/java/jwarehouse/android-examples/platforms/android-2/samples/ApiDemos/src/com/example/android/apis/view/List9.java.shtml)