-
Notifications
You must be signed in to change notification settings - Fork 260
MultiChoiceArrayAdapter tutorial
This tutorial will teach you how to create a very simple list using MultiChoiceArrayAdapter
. The list will show a list with some of Manhattan's tallest buildings.
Create a new Android project using Maven or your IDE of choice, and add references to the ActionBarSherlock and MultiChoiceAdapter library projects.
Add a new activity called MainActivity, and make it derive from SherlockActivity. Edit the XML layout for this activity so that it looks like this:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@android:id/list" />
Now you need an adapter to provide the ListView with items to display. Add the following class to your project:
public class MyArrayAdapter extends MultiChoiceArrayAdapter<String> {
public MyArrayAdapter(Bundle savedInstanceState, Context context, List<String> items) {
super(savedInstanceState, context, R.layout.mca__simple_list_item_checkable_1, android.R.id.text1, items);
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.my_action_mode, menu);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.menu_share) {
Toast.makeText(getContext(), "Share", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
}
Note that you are using the layout R.layout.mca__simple_list_item_checkable_1
for your list items. This is very similar to android.R.layout.simple_list_item_1
, except that the contained view implements Checkable
and is thus able to change its background to reflect its state.
The menu for the action mode is very simple:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_share"
android:icon="@drawable/ic_social_share"
android:showAsAction="always"
android:title="@string/menu_share"/>
</menu>
Now that you have your adapter class ready you can bind it to the ListView. At the end of MainActivity's onCreate method:
ListView listView = (ListView)findViewById(android.R.id.list);
List<String> items = Arrays.asList("One World Trade Center", "Empire State Building", "Bank of America Building", "Chrysler Building");
adapter = new MyArrayAdapter(savedInstanceState, this, items);
adapter.setAdapterView(listView);
adapter.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(this, "Item click: " + adapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
Two things are worth noting here. First, instead of doing listView.setAdapter()
as you'd do with a standard adapter, instead you need to do adapter.setAdapterView()
. Second, in order to know when a list item has been clicked you call setOnItemClickListener()
on the adapter, not on the list as with a standard adapter.
If you run the application now, it will work alright except for one detail: the checked/unchecked state of list items is lost after a configuration change. Fixing this is simple: just add the following method to your activity:
@Override
protected void onSaveInstanceState(Bundle outState) {
adapter.save(outState);
}
By default the list items created this way have a selector that makes their background blue when they are pressed or checked. To change this, just define your own selector and assign it to your list items after inflating them. For instance, the following selector will make your checked items red:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/light_red" android:state_pressed="true"/>
<item android:drawable="@color/light_red" android:state_checked="true"/>
<item android:drawable="@android:color/transparent"/>
</selector>
To apply it, override getViewImpl()
in your adapter class like this:
@Override
protected View getViewImpl(int position, View convertView, ViewGroup parent) {
View view = super.getViewImpl(position, convertView, parent);
view.setBackgroundResource(R.drawable.custom_list_item_background);
return view;
}
Note that in this case this must be done programmatically because we are using the predefined layout R.layout.mca__simple_list_item_checkable_1
. If you are defining your own layout, you can simply set the android:background
attribute of your root element.