Android。屏幕旋转问题后片段停留在 activity

Android. Fragment stays in activity after screen rotation issue

我有两个 activity_main.xml 的变体(针对 portrait/landscape 方向)。在此 activity 中,用户可以选择项目并浏览有关所选项目的详细信息。

在纵向方向上,动态添加到 flFragmentContainer 的片段,在项目选择后,详情片段替换列表片段:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/flFragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>
</LinearLayout>

横向,XML 文件中静态描述的片段:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <fragment
            android:id="@+id/frgTaskList"
            android:name="com.exprod.xchecklist.fragments.TaskListFragment"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            tools:layout="@layout/fragment_task_list" />
        <fragment
            android:id="@+id/frgTaskDetails"
            android:name="com.exprod.xchecklist.fragments.TaskDetailsFragment"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            tools:layout="@layout/fragment_task_details">
        </fragment>
    </LinearLayout>
</LinearLayout>

这是(MainActivity 的)onCreate() 方法的代码。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentManager fragmentManager = getSupportFragmentManager();
        TaskDetailsFragment taskDetailsFragment = (TaskDetailsFragment)fragmentManager.findFragmentById(R.id.frgTaskDetails);
        isDynamicMode = taskDetailsFragment == null || !taskDetailsFragment.isInLayout();
        if(isDynamicMode){
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            Fragment taskListFragment = new TaskListFragment();
            if (savedInstanceState == null) {
                transaction.add(R.id.flFragmentContainer, taskListFragment, TaskListFragment.FRAGMENT_TAG);
            }else{
                transaction.replace(R.id.flFragmentContainer, taskListFragment, TaskListFragment.FRAGMENT_TAG);
            }
            transaction.commit();            
        }
    }

问题: 当我将设备旋转到横向时,我在第一个片段 (TaskListFragment) (onCreateView(), onActivityCreated( ), ... ).这表明旧片段保留在 activity 中并在方向更改时重新创建。 我如何才能最终销毁旧片段?我在网上没有找到答案。

P.S:抱歉我的英语不好...

只需添加到您的 activity @Override public void onSaveInstanceState(Bundle outState) {} 因为此方法在 Android 的 Activity 中实现,它是所有 Activity 的父级,保存了 Fragment。

我看到至少有两种方法可以满足您的需求。

自行更改方向:

this document 中所述,您可以防止自动 Activity 销毁和重新创建并自行处理方向更改。在这种情况下,您将在将新布局扩展到 Activity.

之前删除旧的 Fragment

重新创建Activity后删除旧片段:

您还可以添加一些确定方向的逻辑,如 here 所述(或使用您当前设置 isDynamicMode 的启发式方法),并在 [= 期间手动删除不必要的 Fragments 15=]。

更好的方法:

虽然可以做你想做的事,但我不明白你为什么要这样做 - 你在纵向和横向配置中都使用 TaskListFragment,因此最合乎逻辑的事情是做的是重用它。除了简化事情之外,它还可以让你在方向改变时保持 Fragment 的状态(我相信这对你的情况是可取的)。

感谢 Vasiliy 的回答。我关注这个 link 并添加

android:configChanges="oritentation"

到我的清单文件:

<activity android:name=".MyActivity"
      android:configChanges="orientation"
      android:label="@string/app_name">

并且屏幕旋转时令人讨厌的行为(片段未附加到 activity)消失了