Yoav
Yoav

Reputation: 645

Alphabetical sorted listview with Alphabetic section using ArrayAdapter in Android application

I want to have a listview with a custom adatper, extends ArrayAdapter, where Type has Name field (String). I want to sort the items Alphabitcly (this is not a problem) and then put Alphabetic sections.

For example: A Alpha Any ... C Child ... I ink

Also - results are retrieved from a webservice using Paging, so when user presses the GetMoreResult button, list should be updated accordingly - will notifyDataSetChanged will work?

Upvotes: 0

Views: 10326

Answers (5)

Jeff Hay
Jeff Hay

Reputation: 2645

To make Saad Farooq's answer work with a CursorAdapter, I use something like the following hack in getView():

String thisTitle = getStringValue(cursor, TITLE_NAME);
char thisSection = thisTitle.toUpperCase().charAt(0);
holder.sectionHeader.setText(thisSection);

holder.separator.setVisibility(View.GONE);

// Check if the previous entry was a different alphabetic character
if (cursor.moveToPrevious())
{
     String prevTitle = getStringValue(cursor, TITLE_NAME);
     char prevSection = prevTitle.toUpperCase().charAt(0);
     if (prevSection != prevTitle)
     {
        holder.separator.setVisibility(View.VISIBLE);
     }
     cursor.moveToNext();
}

Note that there are better ways to show a segmented list like this, but this works for a quick hack when needed.

Upvotes: 0

Saad Farooq
Saad Farooq

Reputation: 13402

I was trying the same thing. I tried doing it using the currentChar logic mentioned by Kasper. It appears that the listView() calls are not always in the order you'd expect so that doesn't work very well. My solution is like this:

In the XML add a TextView with visibility GONE like so. This will be your separator tag.

<TextView
    style="?android:attr/listSeparatorTextViewStyle"
    android:id="@+id/separator"
    android:layout_width="fill_parent"
    android:visibility="gone"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white" />

NOTE: I use the Android standard separator style. Of course you can make your own.

Then add a boolean array to you Adapter class with a method something like this

/**
* Method takes the alphabetically sorted ArrayList as argument
*/        
private void assignSeparatorPositions(ArrayList<Items> items) {
        separatorAtIndex = new boolean[items.size()];
        char currentChar = 0;

        for (int i=0; i< items.size(); i++) {
            if ( itemss.get(i).getName().charAt(0) != currentChar ) {
                separatorAtIndex[i] = true;
            } else {
                separatorAtIndex[i] = false;
            }
            currentChar = items.get(i).getName().charAt(0);
        }

}

Finally in you getView() do something like this:

if ( separatorAtIndex[position] ) {
            holder.sectionHeader.setText(""+name.charAt(0));
            holder.sectionHeader.setVisibility(View.VISIBLE);
        } else {
            holder.sectionHeader.setVisibility(View.GONE);
}

This method has the advantage of not requiring you to keep track of the new positions of items after adding a separate header view.

Upvotes: 8

kaspermoerch
kaspermoerch

Reputation: 16570

What you need is a seperator. Use this guide to figure out how to add a seperator.

Then in your Adapter you need a variable that can tell you where in the alphabet you are.

private Char currentChar;

In the getView-method you will then need to determine if you're adding a normal Item or you're adding a seperator. Something like:

if( currentItem.getCharAt( 0 ) != currentChar )
   //add a seperator.
else
   //add an item.

One thing to remember is that you might mix with the indexes of the items, because the ListView will suddenly contain more items than the array. One way to fix this, is to add dummy items (could just be a null object) to the array.

Upvotes: 2

Ramesh Akula
Ramesh Akula

Reputation: 5740

You can download code for listview with alphabets.

http://www.anddev.org/code-snippets-for-android-f33/alphabetical-listview-in-android-t56983.html

Upvotes: 2

barry
barry

Reputation: 4147

notifyDataSetChanged will update the list, yes.

Just remember not to reassign your list object when updating as your list adapter retains a reference to the one you passed it at construction. Just clear it and refill it before calling notifyDataSetChanged.

Upvotes: 1

Related Questions