用户交互后刷新ListView

时间:2012-02-13 22:54:26

标签: android listview baseadapter simpleadapter

在用户从source-SQLite表中删除了一行后,我正在努力更新我的ListView。

我已经搜索了几天的解决方案,并发现了一些建议我使用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 :(得分:0)

更新UI的任何内容都必须在UI线程上运行。试试这个。

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

如果直接更改适配器的基础数据提供程序(如修改数据库时的情况),则必须通知适配器。更简洁的方法是扩展适配器类并覆盖插入,添加,删除等。这样,您不需要做任何通知,因为适配器知道它的后备数据已被修改并将通知任何绑定的视图自动。此方法的另一个优点是您可以修改数据提供程序的底层实现,例如将其移动到XML中,而不会在适配器之外更改代码。

答案 1 :(得分:0)

我找到了解决问题的方法。

找到一个working example我曾经理解过这个问题。

主要的区别是我在对数据库进行了我想要的更改之后在游标上使用了'requery()'。

这是我完成所需更改后的代码:

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{

                  }
                }
          });

Tnx给你@Simon试图帮助我!