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.
Define the listview as usual. Define a RelativeLayout containing the ListView and on the right, a LinearLayout with all the letters. For a better solution, the list of letters could be generated dynamically to only display the letters in the list. Then in the onClick method, add the behaviour to scroll the list :
Android ListView is a view which groups several items and display them in vertical scrollable list. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database.
Set the TextView's tag to A-Z appropiately and set onClick="quickScroll" on all of them. This will scroll to the selected letter onClick, but I believe you can scroll your finger over the alphabet on iPhone and it'll update the list?
Put your list view in a RelativeLayout and put A-Z TextViews in a vertical LinearLayout that is set to layout_alignParentRight="true". Set the TextView's tag to A-Z appropiately and set onClick="quickScroll" on all of them.
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; } }
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With