我是一个聊天应用程序,我使用MergeAdapter在聊天列表列表中显示3个部分。第一部分包括当前在线程中的用户列表。第二部分列出了可以在聊天中添加的不同组(包括1个以上的用户),第三部分是可以在聊天中添加的所有个人用户的列表。列表将如下所示:
———Users currently in chat———
UserA
UserB
UserC
UserD
———Groups to add in chat———
Group1
Group2
Group3
Group4
———Users to add in chat———
User1
User2
User3
User4
用户可以通过在编辑文本字段中键入字符来过滤此列表。我想在进行过滤时会发生IllegalStateException。我无法重现异常,到目前为止唯一的情况是生产应用程序。
例外情况如下:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131558865, class android.widget.ListView) with Adapter(class com.commonsware.cwac.merge.MergeAdapter)]
at android.widget.ListView.layoutChildren()(ListView.java:1582)
at android.widget.AbsListView$CheckForTap.run()(AbsListView.java:4032)
at android.os.Handler.handleCallback()(Handler.java:739)
at android.os.Handler.dispatchMessage()(Handler.java:95)
at android.os.Looper.loop()(Looper.java:145)
at android.app.ActivityThread.main()(ActivityThread.java:5837)
at java.lang.reflect.Method.invoke()(Method.java:-2)
at java.lang.reflect.Method.invoke()(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main()(ZygoteInit.java:1183)
我刚刚见过这个例外。 我正在添加与创建和过滤适配器相关的代码
public void createAndPopulateMergeAdapter(){
MergeAdapter mergeAdapter = new MergeAdapter();
View convertView = LayoutInflater.from(context).inflate(R.layout.header_row, lvRoster, false);
TextView tvHeader = (TextView) convertView.findViewById(R.id.tvRosterHeader);
tvHeader.setText("Users currently in chat");
mergeAdapter.addView(convertView);
Adapter1 adapter1 = new Adapter1();
mergeAdapter.addAdapter(adapter1);
convertView = LayoutInflater.from(context).inflate(R.layout.header_row, lvRoster, false);
tvHeader = (TextView) convertView.findViewById(R.id.tvRosterHeader);
tvHeader.setText("Groups to add in chat");
mergeAdapter.addView(convertView);
Adapter2 adapter2 = new Adapter2();
mergeAdapter.addAdapter(adapter2);
convertView = LayoutInflater.from(context).inflate(R.layout.header_row, lvRoster, false);
tvHeader = (TextView) convertView.findViewById(R.id.tvRosterHeader);
tvHeader.setText("Users to add in chat");
mergeAdapter.addView(convertView);
Adapter3 adapter3 = new Adapter3();
mergeAdapter.addAdapter(adapter3);
lvRoster.setAdapter(mergeAdapter);
}
public void filter(String searchQuery){
// This will filter the results in adapter1’s underlying list used to display the data
adapter1.filter(searchQuery);
// This will filter the results in adapter2’s underlying list used to display the data
adapter2.filter(searchQuery);
// This will filter the results in adapter3’s underlying list used to display the data
adapter3.filter(searchQuery);
mergeAdapter.notifyDataSetChanged();
}
每个适配器的过滤器方法将过滤基础数据源。我在最后调用notifyDataSetChanged以反映列表视图中每个适配器的更改。我使用Realm作为我的数据库,并且所有单独适配器中的基础数据源是RealmResults<>对象,以便我可以直接查询它以应用过滤器。
从TextWatcher的afterTextChanged方法
调用filter方法@Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
我不确定崩溃发生的原因以及导致崩溃的原因。我知道我们需要在每次更改适配器的数据源后调用notifyDataSetChanged()。我的假设是MergeAdapter的notifyDataSetChanged调用每个添加的适配器的notifyDataSetChanged,因此在过滤每个适配器后我不需要调用notifyDataSetChanged。最后一次调用MergeAdapter的notifyDataSetChanged应该没问题。
如果有人能帮助我弄清楚我在这里做错了什么,我真的很感激。
感谢。