RecyclerView 适配器在设备旋转后不更新视图
RecyclerView Adapter not updating views after device rotation
我有一个聊天应用程序,它打开一个到服务器的 Websocket。该应用程序有 2 个模块 -
- chat sdk: 处理连接加来回
消息。
- ui:处理适配器和视图
聊天 UI 在 activity 主持的片段上。
一切正常,但是当我决定在设备轮换上使用持久性时,我遇到了问题。
当我旋转设备时,websocket 重新连接(这是正常的),activity 被重新创建,片段也是如此。
在设备轮换和一些调试之后,我看到我的消息列表已正确填充任何添加的项目(即消息文本),但没有 UI。当我从 EditText 中键入文本并按发送时,该项目正确显示在 UI 中,但是当我收到来自服务器的响应时,即使将消息添加到 messageList 中,UI 也不会更新.
我在类似的帖子中读到 RecyclerView 适配器在旋转后更新旧片段。是这样吗?如果是这种情况,为什么当我从 EditText 发送一条消息时它会正确显示,但当我从我的 WebSocket 的 onMessage 发送消息时却没有?
我尝试了 "android:configChanges="screenSize|orientation|screenLayout"
w/o 任何结果。
我覆盖了 onConfigurationChanged 并强制适配器更新视图,但没有结果
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(messagesAdapter!=null){
messagesAdapter.notifyDataSetChanged();
}
}
我保存片段以在我的 activity
中恢复它
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);
}
}
});
}
}
在 onCreate()
、onCreateView()
或 onActivityCreated()
方法中调用 setRetainInstance(true)
。
我有一个聊天应用程序,它打开一个到服务器的 Websocket。该应用程序有 2 个模块 -
- chat sdk: 处理连接加来回 消息。
- ui:处理适配器和视图
聊天 UI 在 activity 主持的片段上。
一切正常,但是当我决定在设备轮换上使用持久性时,我遇到了问题。 当我旋转设备时,websocket 重新连接(这是正常的),activity 被重新创建,片段也是如此。
在设备轮换和一些调试之后,我看到我的消息列表已正确填充任何添加的项目(即消息文本),但没有 UI。当我从 EditText 中键入文本并按发送时,该项目正确显示在 UI 中,但是当我收到来自服务器的响应时,即使将消息添加到 messageList 中,UI 也不会更新.
我在类似的帖子中读到 RecyclerView 适配器在旋转后更新旧片段。是这样吗?如果是这种情况,为什么当我从 EditText 发送一条消息时它会正确显示,但当我从我的 WebSocket 的 onMessage 发送消息时却没有?
我尝试了 "android:configChanges="screenSize|orientation|screenLayout"
w/o 任何结果。
我覆盖了 onConfigurationChanged 并强制适配器更新视图,但没有结果
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(messagesAdapter!=null){
messagesAdapter.notifyDataSetChanged();
}
}
我保存片段以在我的 activity
中恢复它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);
}
}
});
}
}
在 onCreate()
、onCreateView()
或 onActivityCreated()
方法中调用 setRetainInstance(true)
。