android - RecyclerView 适配器在设备旋转后不更新视图
问题描述
我有一个聊天应用程序,它打开一个到服务器的 Websocket。该应用程序有 2 个模块 -
- chat sdk:处理连接以及来回消息传递。
- 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);
}
}
});
}
}
解决方案
调用setRetainInstance(true)
,onCreate()
或onCreateView()
方法onActivityCreated()
。
推荐阅读
- javascript - Discord bot命令不起作用返回错误
- python - Sanic Python:将文件发送到客户端后删除
- python - 在 windows 中使用 cv2 保存视频并播放
- sql-server - SQL Server - 将纪元转换为日期时间
- javascript - 嵌套列表到数组 - Eloquent JavaScript 第 4 章
- azure - 通过非交互式 powershell 脚本连接到 Microsoft Teams
- python - 如何加快第二个循环依赖于第一个循环的嵌套循环?
- svg - 关节:如何将 icomoon 图标包含到 rappid 的自定义形状中
- excel - 如何从这个excel单元格中的特定文本中提取内容
- kubernetes - 如何在 terraform 中获取 k8s 作业的输出