Элементы дублируются каждый раз, когда я запускаю приложение в ListView с помощью SimpleCursorAdapter

ListView заполняется элементами из Курсора, которые я передаю в SimpleCursorAdapter, но каждый раз, когда я открываю приложение, эти элементы добавляются повторно к списку, постоянно увеличивая его. Когда я использую SimpleAdapter, я делаю что-то вроде этого:

static final ArrayList<HashMap<String, String>> foobar = new 
                                          ArrayList<HashMap<String,String>>();
   SimpleAdapter adapter = new SimpleAdapter(this, foobar, R.layout.list_item, String[] from, int[] to);
   setListAdapter(adapter);

Далее решите мою проблему:

    @Override
    public void onDestroy(){
    super.onDestroy();
       foobar.removeAll(foobar);
    }

Но теперь я не хочу удалять содержимое базы данных, поэтому как решить эту проблему, если у меня есть SimpleCursorAdapter? как этот:

> SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, String[] from, int[] to);

Я пробовал setListAdapter(null) или cursor.close() и многие другие, но безрезультатно...

Теперь это происходит, когда я выхожу из приложения с помощью кнопки «назад» на устройстве. Если я нажму кнопку «домой», когда я вернусь, у меня будет такое же количество элементов. Таким образом, список дублируется каждый раз, когда я выхожу с помощью кнопки «назад».

Решено благодаря ответу Каедиила. Я улучшил прокомментированные строки. Класс отверстия:

public class DataBaseActivity extends ListActivity {

 DataBaseMethods dbmet; //is the class that handle database and auxiliar methods working on it

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list);

    dbmet = new DataBaseMethods(this);
    Cursor mycursor= dbmet.getItems(); // 1. add new cursor


    try{
            if(!mycursor.moveToFirst()){   //2.check if there are items in the database
        dbmet.addItems("Daniel","Son","Karate-kid");
        dbmet.addItems("Silv", "Stalone", "Terminator");
        dbmet.addItems("foo", "bar", "buz");
            } //
            showDatabaseContent();
    }

    finally{
        dbmet.close();
    }
}


public void showDatabaseContent(){

     DataBaseMethods dbmet = new DataBaseMethods(this);
    try{

        Cursor cursor = dbmet.getItems();
        SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.item_list, cursor, dbmet.FROM, TO);
        setListAdapter(myadapter);
    }
    finally{
        dbmet.close();
    }

}

person AlexAndro    schedule 02.12.2011    source источник
comment
вашей проблемы нет в представленном вами коде. Я предполагаю, что ваши данные жестко закодированы, и вы, вероятно, каждый раз просто сохраняете их в своей базе данных. посмотрите на свой вспомогательный класс db или на то, где вы вызываете его методы в onCreate.. если вы не можете найти его, опубликуйте код..   -  person Joe    schedule 02.12.2011


Ответы (2)


Хм, эта строка подозрительна:

Если это имеет значение, я заполняю базу данных в этом действии onCreate(), но я пытался заполнить его также из другого действия, и я получаю такое же поведение для списка.

При заполнении вызова базы данных вы проверяете, заполнена ли уже база данных?

Похоже, вы просто продолжаете добавлять новые копии в БД, на которые указывает курсор.

person Kaediil    schedule 02.12.2011
comment
Нет, я не .... Увидев ваш ответ, я попытался использовать что-то с `if cursor.isNull(0)`, но каждый раз генерировалось исключение индекса, что бы я ни ставил. Какой-нибудь совет, пожалуйста? - person AlexAndro; 03.12.2011
comment
Хорошо, глядя на отредактированный код, вы определенно собираетесь продолжать добавлять его в базу данных. Вы можете (хотя это несколько неэффективно) сделать следующее: Cursor cursor = dbmet.getItems(); if(!cur.moveToFirst()) Этот вызов moveToFirst вернет false, если он пуст. - person Kaediil; 03.12.2011
comment
Это работает :)) Честно говоря, я хотел попробовать это раньше, но меня обескуражил cur.isNull(0), и я больше не пробовал, думая, что это почти то же самое. Спасибо! Я обновлю вопрос с некоторыми комментариями, чтобы решение было видно. - person AlexAndro; 03.12.2011
comment
Круто, рад, что смог помочь, не забудьте также отметить ответ на вопрос, спасибо. - person Kaediil; 03.12.2011

public void showDatabaseContent(){

     DataBaseMethods dbmet = new DataBaseMethods(this);
    try{

        Cursor cursor = dbmet.getItems();
        SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this, R.layout.item_list, cursor, dbmet.FROM, TO);
        setListAdapter(myadapter);
       -->> myadapter.notifyDataSetChanged(); <<----
    }
    finally{
        dbmet.close();
    }


}

Вам нужно вызвать notifyDataSetChanged(), чтобы сообщить списку, что он аннулирует себя ТОЛЬКО с новыми данными.

NOTE: Если проблема связана с классом базы данных. Убедитесь, что вы не вставляете элементы в базу данных каждый раз при запуске приложения. Я мог бы смешать вашу проблему, если элементы дублируются в списке или в базе данных. Я глубоко уверен, что вы повторно вставляете данные каждый раз, когда запускаете приложение.

person Nikola Despotoski    schedule 02.12.2011
comment
Нет, не решает. Я также попытался удалить dbmet = new DataBaseMethods(this) из этого метода, думая, что он вызывается дважды. Если я вставляю каждый раз, когда запускаю приложение, убедитесь, что я не хотел бы этого делать, но я не знаю, как это сделать. Единственное место, где я вставляю, это здесь, onCreate(), если я не добавлю эти 3 строки кода, у меня не будет данных, я проверял. Любой совет? - person AlexAndro; 03.12.2011