Today in France, we celebrate ""
Posts
04/07/10 : Android sorting
16/06/10 : Flex XML parsing
15/06/10 : Android settings
14/06/10 : Pax daemon
10/06/10 : Bundle CPU %
04/06/10 : Wicket CheckBox
03/06/10 : Thread monitor

By tag
Ajax
Android
AspectJ
Flex
Java
JMX
OSGi
Shell
Wickets

Here are some lights and tips on various Object Oriented Programming aspects that I would have dealt with during my software development and architecture activities..., for sharing.

"Beauty is an inexhaustible source of happyness for the one who discovers it" (Alexis Carrel)



Sunday, 4 July 2010

Android ListActivity sorting

Question : how to sort on a given Android ListActivity column ?

Answer :
- attach a setOnClickListener to its corresponding TextView instance
- think about the Comparator interface
- after comparison, call notifyDataSetChanged on your list view adapter


Details :

Step #1 : Layout definition :
<LinearLayout
android:layout_marginTop="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginLeft="10dip"
android:background="@drawable/background">
<TextView
android:id="@+id/cName"
android:textColor="@drawable/black"
android:layout_width="0dip"
android:layout_weight="46"
android:layout_height="25dip"
android:text="@string/bdle_name"
android:gravity="center"
/>
<TextView
...
/>
<TextView
...
/>
</LinearLayout>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="verticalhorizontal"
android:layout_marginRight="15dip"
android:layout_marginLeft="15dip"
android:layout_marginTop="5dip"
/>

Step #2 : given the BundleInfo class that holds the different attributes/columns of the list to be displayed, attach the listener to the TextView column subject to sorting, here : cName

public final class RestClient extends ListActivity
{
/**
* Bundles list
*/
private ArrayList<BundleInfo> bundles = new ArrayList<BundleInfo>();

/**
* List view adapter
*/
private CustomAdapter adapter = null;

/**
* list sorting type
*/
private SortType sortType = SortType.NONE;

/**
* Sorting order (-1 if reversed)
*/
private int sign = 1;

/**
* Name column widget
*/
private TextView cName = null;

/**
* Enumerated type for column sorting
*/
private enum SortType
{NAME, // by 'Name'
// OTHER, // by 'Other' column
NONE}

/**
* List refresh handler
*/
private Runnable refresh = new Runnable()
{

@Override
public void run()
{
// refresh your list here
// ...

if (!bundles.isEmpty())
switch (sortType)
{
case NAME:
comp = new SortByName();
Collections.sort(bundles, comp);
break;

// other cases as needed

default:
break;
}
else sortType = SortType.NONE;
adapter.notifyDataSetChanged();
}
};

@Override
public void onCreate(Bundle savedInstanceState)
{
// Setting activity content
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Other initializations
// ...
adapter = new CustomAdapter(this, R.layout.main, R.id.name, bundles);
setListAdapter(adapter);

// Sorting
sortType = SortType.NONE;
cName = (TextView) findViewById(R.id.cName);
cName.setOnClickListener(new ImageButton.OnClickListener()
{
public void onClick(View v)
{
sign = ((sortType == SortType.NAME) ? sign * -1 : sign);
sortType = SortType.NAME;
if (!isRunning) runOnUiThread(refresh);
}
});
}

/**
* List view adapter
*/
private final class CustomAdapter extends ArrayAdapter<BundleInfo>
{
// List view adapter class body
// ...
}
}
The 'refresh' thread being responsible for refreshing the view whenever needed.


Step #3 : for each column you wish to apply a sorting, add such an inner class definition :
/**
* List comparator for sorting by 'name'
*/
private final class SortByName implements Comparator<BundleInfo>
{
public int compare(BundleInfo i1, BundleInfo i2)
{
return i1.getBundleName().compareTo(i2.getBundleName()) * sign;
}
}
Previous Post Next Post