Anubis
Anubis

Reputation: 1222

ListView and BaseAdapter implementation showing duplicate elements

I have a ListView supported by my custom BaseAdapter implementation with a database behind it all. When I first insert an item into my database, everything is fine. However, when I add another item, my ListView suddenly displays 3 items instead of 2. If I add another item, the ListView updates and suddenly I see 5 items. When I hit the back button and go back to the previous activity and launch the ListView activity again, it shows the right number of items again. So either my ListView or my adapter isn't being updated correctly but I can't see where it's going wrong. I'd very much appreciate some help.

My code:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.goals_main_screen);
    mListView = (ListView) findViewById(R.id.goal_listview);
    customGridAdapter = new CustomGridViewAdapter(this, R.layout.card_grid_item, gridArray);
    customGridAdapter.registerDataSetObserver(new DataSetObserver(){
        @Override
        public void onChanged(){
            retrieveCurrentGoals();
        }
    });
    mListView.setAdapter(customGridAdapter);
    mListView.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            goToDetailedGoalView((int) id);
        }
    });
    retrieveCurrentGoals();
}

private void retrieveCurrentGoals(){
    String[] projection = {DatabaseHelper.KEY_ROWID, DatabaseHelper.KEY_GOAL_ID};
    Cursor c = getContentResolver().query(MyContentProvider.CONTENT_URI_USER_GOALS, projection, null, null, null);
    c.moveToFirst();
    for(int i=0; i<c.getCount();i++){
        String [] goalData = getGoalData(c.getInt(1));
        gridArray.add(goalData);
        c.moveToNext();
    }
    c.close();
}

private String[] getGoalData(int id){
    String[] projection = {DatabaseHelper.KEY_GOAL_TITLE, DatabaseHelper.KEY_GOAL_CATEGORY};
    String selection = "_id = " + id;
    Cursor c = getContentResolver().query(MyContentProvider.CONTENT_URI_GOALS, projection, selection, null, null);
    if(c.moveToFirst()){
        String[] data = {"", "", ""};
        data[0] = c.getString(0);
        data[1] = Integer.toString(c.getInt(1));
        data[2] = String.valueOf(id);
        return data;
    }
    c.close();
    return null;
}

private void goToDetailedGoalView(int id){
    Intent i = new Intent(this, GoalCardDetail.class);
    i.putExtra(SharedData.GOAL_ID.getValue(), id);
    startActivityForResult(i, 0);
}

public void toGoalSelectionScreen(View v){
    Intent i = new Intent(this, DisplayCardActivity.class);
    startActivityForResult(i,GO_TO_GOAL_CARD_SCREEN);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if(requestCode == GO_TO_GOAL_CARD_SCREEN && resultCode == RESULT_OK){
        System.out.println("ListView holds: " + mListView.getCount());
        customGridAdapter.notifyDataSetChanged();
    }
}

Upvotes: 0

Views: 261

Answers (4)

Pankaj Arora
Pankaj Arora

Reputation: 10274

You should clean your array before adding the data in it. as leave and again come to current activity or fragment will leads to adding data each time in your array every time,thats is why your are getting dublicate data.just clean your gridarray and goal data before you adding data to it.that's it.

Upvotes: 0

aldorain
aldorain

Reputation: 790

Does the Cursor in getGoalData() have expected length (previous length + 1) ?

I strongly recommend using CursorLoader class and implementing LoaderCallbacks in the Activity or Fragment.

Upvotes: 0

dreambit.io dreambitio
dreambit.io dreambitio

Reputation: 1902

Maybe It happens because when you call retrieveCurrentGoals() you always read all rows in database and attach they to your gridArray.

Initially you have added first item, at second time you have added first and second and etc.

As one of possible solutions call clear method of you arrayList before set new data

Upvotes: 0

silwar
silwar

Reputation: 6518

Try clearing Array before adding new elements

  private void retrieveCurrentGoals(){
     gridArray.clear();
     String[] projection = {DatabaseHelper.KEY_ROWID, DatabaseHelper.KEY_GOAL_ID};
     Cursor c = getContentResolver().query(MyContentProvider.CONTENT_URI_USER_GOALS, projection, null, null, null);
     c.moveToFirst();
     for(int i=0; i<c.getCount();i++){
       String [] goalData = getGoalData(c.getInt(1));
       gridArray.add(goalData);
       c.moveToNext();
     }
    c.close();
   }

As you said first time its retrieving perfectly but second time and on it starts giving duplicate values. This might be due to you are using class variable gridArray. Check first line in method which remove all element prior to adding new set of data

Upvotes: 2

Related Questions