Обновить ListView после взаимодействия с пользователем - PullRequest
0 голосов
/ 14 февраля 2012

Я пытаюсь обновить ListView после того, как пользователь удалил строку из таблицы source-SQLite.

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

Я пытаюсь использовать BaseAdapter, но я не уверен, посмотрев на LogCat, что этосделано правильно.

Это код, который я использую:

ArrayList<HashMap<String,String>> results = new ArrayList<HashMap<String,String>>(); 

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    openAndQueryFav();
    displayResultList();


    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    lv.setOnItemClickListener(new OnItemClickListener() {

      public void onItemClick(AdapterView<?> parent, View view,
          int position, long id) {
              HashMap<String, String> item = (HashMap<String, String>) parent.getAdapter().getItem(position);
              String Start = item.get("Start").toString();
              String Name = item.get("Name").toString();
              try{
                  DBAdapter dbHelper = new DBAdapter(getBaseContext());
                  newDB = dbHelper.getWritableDatabase();
                  Cursor favorite = newDB.rawQuery("SELECT Start FROM " +
                            tableFav + " WHERE Start='" + Start + "'", null);
                  favorite.moveToFirst();

                      if(favorite.getCount() > 0){
                          newDB.execSQL("DELETE FROM " +
                                    tableFav + " WHERE start='" + Start + "'");
                          HeaderViewListAdapter adapterwrap = (HeaderViewListAdapter) parent.getAdapter(); 
                          BaseAdapter adapter = (BaseAdapter) adapterwrap.getWrappedAdapter();

                          adapter.notifyDataSetChanged();


                      }else{

                      }
              }catch(Exception e){

                  Log.d("Events", "catch, exception." + e.toString());
              }finally{

                  newDB.close();
              }
            }
      });

}



private void displayResultList() {

    ListAdapter adapter = new SimpleAdapter(
            this,
            results,
            R.layout.list,
            new String[] {"Start","Name","date"},
            new int[] {R.id.item_id,R.id.item_name,R.id.item_date}
            );
    setListAdapter(adapter);

    }

Я, должно быть, совершаю что-то ужасное неправильно!Потому что, когда я пытаюсь запустить его, я получаю это в LogCat:

02-14 00:28:54.777: D/Events(9172): catch, exception.java.lang.ClassCastException: android.widget.SimpleAdapter

И если я пытаюсь поместить:

HeaderViewListAdapter adapterwrap = (HeaderViewListAdapter) parent.getAdapter(); 
BaseAdapter adapter = (BaseAdapter) adapterwrap.getWrappedAdapter();

вне try {}, эта ошибка в LogCat:

02-13 23:04:53.107: E/AndroidRuntime(9066): FATAL EXCEPTION: main
02-13 23:04:53.107: E/AndroidRuntime(9066): java.lang.ClassCastException: android.widget.SimpleAdapter
02-13 23:04:53.107: E/AndroidRuntime(9066):     at com.myapplication.Favorite$1.onItemClick(Favoritter.java:74)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.widget.ListView.performItemClick(ListView.java:3382)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.os.Handler.handleCallback(Handler.java:587)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.os.Looper.loop(Looper.java:144)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at android.app.ActivityThread.main(ActivityThread.java:4937)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at java.lang.reflect.Method.invokeNative(Native Method)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at java.lang.reflect.Method.invoke(Method.java:521)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-13 23:04:53.107: E/AndroidRuntime(9066):     at dalvik.system.NativeStart.main(Native Method)

Может ли кто-нибудь указать мне правильное направление, чтобы обновлять мой список после выполнения задания?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 февраля 2012

Я нашел решение своей проблемы.

Нашел рабочий пример , который я использовал для понимания проблемы.

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

Это код после внесения необходимых изменений:

newDB = new DBAdapter(this.getApplicationContext());

        c = newDB
        .getWritableDatabase()
        .rawQuery("SELECT _ID, Start, Name, Time, Fav FROM " +
                tableName + " WHERE Fav='1'" , null);
        ListAdapter adapter = new SimpleCursorAdapter(
                this,
                R.layout.list, c,
                new String[] {"Start","Name","Time"},
                new int[] {R.id.item_id,R.id.item_name,R.id.item_time}
                );
        setListAdapter(adapter);

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

        lv.setOnItemClickListener(new OnItemClickListener() {

          public void onItemClick(AdapterView<?> parent, View view,
              int position, long id) {
                String Start = c.getString(c.getColumnIndex("Start"));
                  try{
                      newDB.getWritableDatabase().execSQL("UPDATE " +
                                        tableName + " SET Fav='0' WHERE Start='" + Start + "'");
                      c.requery();

                  }catch(Exception e){

                      Log.d("Events", "catch, exception." + e.toString());
                  }finally{

                  }
                }
          });

Спасибо тебе @Simon за попытку помочь мне!

0 голосов
/ 14 февраля 2012

Все, что обновляет пользовательский интерфейс, должно выполняться в потоке пользовательского интерфейса.Попробуй это.

runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

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

...