I trying out the ListView
example found in the Android API guide. More or less I've copied the code from the example into an activity (I only left out the progressbar
for now).
Everything works, except that the ListView
shows duplicates of each contact that I have on my device (running a Nexus 7, with Android 4.2).
Each contact get's duplicated 6-7 times in the listview
. The cursor I'm using already returns too many results (it should only return 3 items as I only have three contacts on my Nexus atm.). When I checked the RAW_CONTACT_ID
the duplicates always point to the same id values (i.e. I only get 3 unique ID's).
This would suggest that it's not my view code which has some problem.
So the question is what could be going wrong in the adapter?
Why is the cursor returning duplicates for all the contacts? Or is there something on the device that causes these duplicates to be returned.
I've looked through other questions on SO but none seem to be about this particular issue.
public class ThemeSelectorActivity extends ListActivity implements LoaderManager.LoaderCallbacks{ private static final String TAG = "ThemeSelector"; // The rows that we will retrieve from the db (Contacts used as dummy data) static final String[] PROJECTION = new String[] {ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME}; // The select criteria for fetching contacts static final String SELECTION = "((" + ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Data.DISPLAY_NAME + " != '' ))"; // The Adapter being used to display the list's data SimpleCursorAdapter mAdapter; @Override public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "Create..."); super.onCreate(savedInstanceState); // set the listview to be selectable getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); // For the cursor adapter, specify which columns go into which views String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME}; int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1 // Create an empty adapter we will use to display the loaded data. // We pass null for the cursor, then update it in onLoadFinished() mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, fromColumns, toViews, 0); setListAdapter( mAdapter ); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); } // Called when a new Loader needs to be created public Loader onCreateLoader(int id, Bundle args) { // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader(this, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, null); } // Called when a previously created loader has finished loading public void onLoadFinished(Loader loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); } // Called when a previously created loader is reset, making the data unavailable public void onLoaderReset(Loader loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } @Override /** * Start activity that shows a preview of the selected theme */ public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); //String item = (String) getListAdapter().getItem(position); //Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show(); } }