带有com.commonsware.cwac.merge.MergeAdapter

时间:2017-02-28 21:50:49

标签: android commonsware-cwac

我是一个聊天应用程序,我使用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应该没问题。

如果有人能帮助我弄清楚我在这里做错了什么,我真的很感激。

感谢。

0 个答案:

没有答案