I'm fairly new to Android so I may be doing something wrong here which I hope someone here can spot.
I application runs a ListActivity which displays a list of contacts from the native phone book and displays some data, name and phone number along with a check box to allow the user to select multiple contacts.
To do this I have created a Contact object which is populated with data produced by querying the contacts, i.e. People.NAME, People.NUMBER etc... I pull out all the contacts, create a Contact object for each and add it to a list which I then pass to a sub class of an ArrayAdapter which I have called ContactItemArrayAdapter. I override the getView() method so that each Contact obejct from the list populates a custom TexView objects for each row in the list. My activity extends ListActivity and implements the onListItemClick(....) method which logs the details of the contact selected and sets the checkbox checked or unchecked.
Everything works as it should, the Contacts objects are populated and the list of contact details along with a check box is displayed. The problem arises when I run the application and check a checkbox for a row. When the checkbox is clicked the opposite checkbox in the list is shown as checked! When I click it again the correct one checked! Clicking it again unchecks the opposite box, then another click unchecks the correct box!
Its very strange as I see the correct contact details and position value in the list logged out in the server log! I cannot understand why it is checking/unchecking the wrong checkbox in the list.
Here's my code for the Activity which creates the Contact objects and passes it to the ContactItemArrayAdapter and listens for click on an item in the list.
Using java Syntax Highlighting
- public class SelectContacts extends ListActivity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- populateContactsLayout();
- }
- /**
- *
- */
- private void populateContactsLayout() {
- ListView listView = getListView();
- listView.setItemsCanFocus(false);
- listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- listView.setTextFilterEnabled(true);
- queryContacts();
- }
- /**
- * Utility method for querying contacts and displaying them
- * @param nameClause
- */
- private void queryContacts() {
- List<Contact> contacts = new ArrayList<Contact>();
- String query = People.NUMBER + " is not null and " + People.NAME + " like '%'";
- Cursor managedCursor =
- managedQuery(People.CONTENT_URI,
- new String[] {People._ID,People.NAME, People.TYPE, People.NUMBER},
- query, null, People.DEFAULT_SORT_ORDER);
- while(managedCursor.moveToNext()) {
- Contact contact = new Contact(managedCursor.getString(managedCursor.getColumnIndexOrThrow(People._ID)),
- managedCursor.getString(managedCursor.getColumnIndexOrThrow(People.NAME)),
- managedCursor.getString(managedCursor.getColumnIndexOrThrow(People.TYPE)),
- managedCursor.getString(managedCursor.getColumnIndexOrThrow(People.NUMBER)));
- contacts.add(contact);
- Log.e("SelectContacts", contact.toString());
- }
- ArrayAdapter<Contact> arrayAdapter = new ContactItemArrayAdapter(this, R.layout.select_contacts, contacts);
- setListAdapter(arrayAdapter);
- }
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
- Contact contact = (Contact)l.getItemAtPosition(position);
- CheckBox checkBox = (CheckBox)l.findViewWithTag(contact.getId());
- Log.e("SelectContacts", checkBox.getTag().toString());
- checkBox.setChecked(!checkBox.isChecked());
- Log.e("SelectContacts", "contact with name "+contact.getName()+" and position "+position+" was clicked");
- }
- }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4
Here's my ContactItemListAdapter which overrides the getView() method.
Using java Syntax Highlighting
- public class ContactItemArrayAdapter extends ArrayAdapter<Contact> {
- private final int resource;
- /**
- *
- * @param context
- * @param resource
- * @param textViewResourceId
- * @param objects
- */
- public ContactItemArrayAdapter(Context context, int resource, int textViewResourceId, List<Contact> objects) {
- super(context, resource, textViewResourceId, objects);
- this.resource = resource;
- }
- /**
- *
- * @param context
- * @param textViewResourceId
- * @param objects
- */
- public ContactItemArrayAdapter(Context context, int textViewResourceId, List<Contact> objects) {
- super(context, textViewResourceId, objects);
- this.resource = textViewResourceId;
- }
- @Override
- public View getView(int position, View view, ViewGroup parent) {
- if(view == null) view = View.inflate(getContext(), resource, null);
- Contact contact = (Contact)getItem(position);
- TextView nameView = (TextView) view.findViewById(R.id.name);
- nameView.setText(contact.getName());
- TextView labelView = (TextView) view.findViewById(R.id.label);
- labelView.setText(contact.getLabel());
- TextView numberView = (TextView) view.findViewById(R.id.number);
- numberView.setText(contact.getPhoneNumber());
- CheckBox checkBox = (CheckBox) view.findViewById(R.id.selected);
- checkBox.setTag(contact.getId());
- return view;
- }
- }
Parsed in 0.034 seconds, using GeSHi 1.0.8.4
My layout for the activity looks like this.
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:orientation="horizontal">
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:paddingLeft="5dip" android:orientation="vertical"
- android:layout_weight="1">
- <ListView android:id="@+id/android:list"
- android:layout_width="fill_parent" android:layout_height="fill_parent" />
- <TextView android:id="@+id/name" android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:gravity="center_vertical" android:singleLine="true"
- android:paddingRight="6dip" android:layout_alignParentTop="true"
- android:layout_width="wrap_content" />
- <TextView android:id="@+id/label" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:layout_marginTop="2dip"
- android:singleLine="true" android:textAppearance="?android:attr/textAppearanceSmall"
- android:textStyle="bold" android:layout_below="@+id/name" />
- <TextView android:id="@+id/number" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:layout_marginLeft="5dip"
- android:singleLine="true" android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_toRightOf="@id/label" android:layout_alignBaseline="@id/label" />
- </RelativeLayout>
- <CheckBox android:id="@+id/selected" android:layout_height="fill_parent"
- android:layout_weight="0" android:layout_width="wrap_content"
- android:layout_marginRight="5dip" android:focusable="false"
- android:clickable="false" />
- </LinearLayout>
Parsed in 0.006 seconds, using GeSHi 1.0.8.4
Any advice would be very much appreciated



