当前位置: 首页 > 知识库问答 >
问题:

设备旋转后不更新视图

红朝
2023-03-14

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

  1. chat sdk:处理连接和来回消息传递。
  2. 用户界面:处理适配器和视图

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

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

经过设备旋转和一些调试,我看到我的消息列表被正确填充了任何添加的项目(即消息文本),但没有用户界面。当我从编辑文本中键入文本并按发送时,该项目会正确显示在用户界面中,但是当我收到服务器的响应时,即使消息被添加到消息列表中,用户界面也不会更新。

我在类似的帖子中读到,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());
}

来自websocch的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);

                }
            }
        });
    }
}

共有1个答案

俞涵涤
2023-03-14

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

 类似资料:
  • 我正在编写一个应用程序,它有一个带有按钮和图像的菜单。我按下按钮,按钮的标签从“录制曲目”更改为“停止录制”。问题是,当我旋转设备时,带有按钮的活动会被操作系统终止。因此,我知道我必须在数据在方法中被杀死之前保存数据,然后在我的method中恢复数据。类似这样: 和: 虽然它完美地恢复了我的图像,但我的菜单仍然有问题:由于某些原因,它总是保持为“空”,因此它永远不会更改按钮的标签,尽管每次“活动”

  • 问题内容: 我有一个不使用自动布局的UIView,并且根据其在主视图中X和Y坐标的百分比显示了一些组件。 以前,我会运行一个函数来更新它们在didRotateFromInterfaceOrientation中的位置,但是我看到现在iOS8中已弃用此功能。 我看过viewWillTransitionToSize,但是它给出了奇怪的结果,并且似乎没有viewDidtransitionToSize函数。

  • 我有一个带有子视图控制器的视图控制器。 应强制A始终保持纵向,但应允许B自由旋转。 我知道shouldAutorotate应该适用于任何视图控制器及其子级,但有什么方法可以绕过它吗?看起来我可以使用shouldAutorotateToInterfaceOrientation,但这在iOS 8中被阻止了。 我想保持视频播放器静态(因此无论设备方向如何,水平视频始终是水平的),而控制层子视图覆盖允许自

  • 我想做的是: 由父视图控制器管理的父视图不应旋转。 由子视图控制器管理的子视图应该旋转到所有方向。 我所尝试的: 家长视图控制器 儿童视图控制器 Xcode部署信息中支持的方向设置为所有四个。 我得到的: 没有视图的旋转。如果将父视图的旋转设置为“全部”,则所有视图将一起旋转。所以要么全有要么全无。 更新 当我尝试放置UIDeviceOrientationIDChangeNotification的

  • 我正在开发简单的游戏。我有cca。50个矩形排列在10列5行中。以某种方式将它们放入整个屏幕是没有问题的。但是当我旋转画布时,假设大约7°角,旧的坐标不适合坐标的新位置。在构造函数中,我已经创建并定义了那个矩形的位置,在onDraw方法中,我正在绘制这个矩形(当然有aready旋转)bud我需要一些与当前矩形碰撞的方法。我尝试使用这样的东西(我确实围绕屏幕的中心点旋转) 但是它不起作用(因为它给了