2014-11-03 133 views
0

我正在构建一个应用程序,它是根据与服务器通信的Futuretask线程动态填充/清除数组列表。ArrayAdapter刷新数据

问题是,当我添加新的对象到我arrayadapter以任何方式我称之为notifyDataSetChangedsetNotifyOnChange

(例如添加项目之后,我也尝试做一些postadd函数调用notifyDataSetChanged ,或者甚至试图在适配器构造函数添加setNotifyOnChange,或添加之前(adapter.setNotifyOnChange(真))在此Futuretask它只是冻结线程,并导致应用程序故障)

。没有notifyonchange当我滑动我的手指来调用ArrayAdapter的getView()它的作品,但这是一个不受欢迎的行为。

注意:我正在通过静态变量引用访问适配器。

注意#2:我不认为一遍又一遍地创建新的适配器是一个明智的选择。

/编辑:

我的删除方法是这样的:

public void remove (int itemid) { 
     for (ContactItem i : items) 
      if (i.ID == itemid) 
       items.remove(i); 
    } 

(和它挂到底在最后pharantesis)

回答

0
  1. 使用静态变量的引用意味着你应该仔细地在线程中。据我所知,适配器只在UI线程中更新数据。
  2. 你应该知道的另一件事是你应该实现getCount()函数来返回正确的数字。 我的列表视图没有更新我的数据时遇到问题。即使我触发onDatasetChange()。我忘了利用getCount()函数
1
  1. 传递一个弱引用的活动在其他线程,这样你就不会泄漏的环境。

    WeakReference<Activity> mRef_Activity = new WeakReference<Activity>(activity); 
    
  2. 从该线程运行主活动的ui线程上的notify更新。

    final Activity activity = mRef_Activity.get(); 
        if(activity != null) 
         activity.runOnUiThread(new Runnable() { 
    
          @Override 
          public void run() { 
    
           ArrayAdapter<String> adapter = activity.getAdapter(); 
           adapter.notifyDataSetChanged(); 
    
          } 
         }); 
    

注意,如果你正在运行,而不是一个可调用或可运行的异步任务,你可以把在异步的postExecute的通知更新,因为它是从主UI线程回调。

+0

你好,你的回答帮助我谢谢你,但我也遇到了非常奇怪的错误。我还添加了setNotifyOnChange(false);到适配器的构造函数,所以它不会被隐式调用,当我试图添加/从列表中删除,但仍然有时这种调用发生在我删除和整个应用程序挂起时,当我点击屏幕这就是我得到的。 – Smarty77 2014-11-04 21:39:30

+0

java.lang.IllegalStateException:适配器的内容已更改,但ListView未收到通知。确保适配器的内容不会从后台线程修改,而只能从UI线程修改。确保您的适配器在其内容更改时调用notifyDataSetChanged()。[在ListView(2131427350,类android.widget.ListView)与Adapter(类censored.ui.adapters.ContactsAdapter)] – Smarty77 2014-11-04 21:39:54

+0

您提到的函数的文档“如果设置为false,调用者必须手动调用notifyDataSetChanged()这些更改反映在附加视图中,默认值为true,并调用notifyDataSetChanged()将该标志重置为true。“似乎需要在调用notifyDataSetChanged()之后重置它。 – NameSpace 2014-11-05 08:22:04