首页 > 解决方案 > RecyclerView 适配器在设备旋转后不更新视图

问题描述

我有一个聊天应用程序,它打开一个到服务器的 Websocket。该应用程序有 2 个模块 -

  1. chat sdk:处理连接以及来回消息传递。
  2. ui:处理适配器和视图

聊天 UI 位于活动托管的片段上。

一切正常,但是当我决定对设备旋转使用持久性时,我遇到了问题。当我旋转设备时,websocket 重新连接(这是正常的),活动被重新创建,片段也是如此。

在设备旋转和一些调试之后,我看到我的 messageList 正确填充了任何添加的项目(即消息文本),但不是 UI。当我从 EditText 键入文本并按发送时,该项目会正确显示在 UI 中,但是当我收到来自服务器的响应时,即使将消息添加到 messageList,UI 也不会更新。

我在类似的帖子中读到 RecyclerView 适配器在旋转后更新旧片段。是这样吗?如果是这种情况,为什么当我从 EditText 发送消息时它会正确显示,但从我的 WebSocket 的 onMessage 时却没有?

我试过"android:configChanges="screenSize|orientation|screenLayout"没有任何结果。我覆盖 onConfigurationChanged 并强制适配器更新视图,但没有结果

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {

    super.onConfigurationChanged(newConfig);

    if(messagesAdapter!=null){
        messagesAdapter.notifyDataSetChanged();
    }
}

我保存片段以在我的活动中恢复它

public class MessageActivity extends AppCompatActivity {
private MessageFragment fragment;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_message);


    if (savedInstanceState == null) {
        fragment = MessageFragment.newInstance();

        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, fragment)
                .commitNow();
    }else{
        fragment = (MessageFragment) getSupportFragmentManager().getFragment(savedInstanceState, "messageFragment");
    }

}

@Override
public void onBackPressed() {

    finishAffinity();
}


@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    //Save the fragment's instance
    getSupportFragmentManager().putFragment(outState, "messageFragment", fragment);
}}

我还保存和检索我的消息列表

 @Override
public void onSaveInstanceState(@NonNull Bundle outState) {

    super.onSaveInstanceState(outState);
    //saving the state of the chat
    outState.putParcelableArrayList("messages", messageArrayList);
    try {
        Log.d(TAG, "messagelist in save instance " + messageArrayList.size());
    }catch (NullPointerException e){
        e.printStackTrace();
    }
    outState.putString("dialogId", messageArrayList.get(0).getDialogId());
}

来自 websocket 的 onMessage

@Override
public void onMessage(ArrayList<Message> data) {

    if (!messageArrayList.isEmpty() && messageArrayList.get(messageArrayList.size() - 1).getServerMessageType() == Constants.TYPE_TYPING_ON) {
        messageArrayList.remove(messageArrayList.size() - 1);
    }
    this.messageArrayList.addAll(data);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && isFragmentAttached) {

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {

                if (omiliaClient != null) {
                    updateUi(messageArrayList, omiliaClient.user2);

                }
            }
        });
    }
}

标签: androidandroid-recyclerviewrotationfragmentadapter

解决方案


调用setRetainInstance(true),onCreate()onCreateView()方法onActivityCreated()


推荐阅读