Android 如果通过XML添加,则替换片段时没有生命周期

Android 如果通过XML添加,则替换片段时没有生命周期,android,android-fragments,Android,Android Fragments,我遇到了这样一个问题:替换通过XML添加的初始片段不会调用任何破坏性生命周期回调,例如,onDetach(),onDestroy(),onDestroyView(),onStop(),等等。这是一个问题,因为我想在onDetach()中执行一个操作 这是我的设置。按照google developers docs()所说的内容,我创建了一个布局,activity_main.xml,其中包含一个片段 <?xml version="1.0" encoding="utf-8"?> <R

我遇到了这样一个问题:替换通过XML添加的初始片段不会调用任何破坏性生命周期回调,例如,
onDetach()
onDestroy()
onDestroyView()
onStop()
,等等。这是一个问题,因为我想在
onDetach()
中执行一个操作

这是我的设置。按照google developers docs()所说的内容,我创建了一个布局,activity_main.xml,其中包含一个片段

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/sky_2"
    tools:context=".activity.MainActivity"
    tools:ignore="UselessParent,contentDescription">

    <fragment
        android:id="@+id/frag_container"
        android:name="com.example.GameFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <include layout="@layout/footer" />
</RelativeLayout>
当我的应用程序启动时,它会按预期启动我的
GameFragment
。文件指出

当系统创建此活动布局时,它会实例化每个活动布局 在布局中指定的片段,并调用onCreateView()方法 对于每个片段,检索每个片段的布局。系统插入 片段直接返回的视图,而不是 元素

我的GameFragment
onCreateView()
回调确实被调用,所有东西都被初始化,我能够执行所有功能。当我更改选项卡时,问题就出现了。我通过将当前片段替换为新片段来更改选项卡。这是我正在使用的函数

public void addFragmentReplace(int containerId, @NonNull Fragment fragment) {
    // check if the fragment has been added already
    Fragment temp = mFragmentManager.findFragmentByTag(fragment.getClass().getSimpleName());
    if (!Utils.checkIfNull(temp) && temp.isAdded()) {
        return;
    }

    // replace fragment and transition with animation
    try {
        if (!Utils.isStringEmpty(getTopFragment().getTag()) && getTopFragment().isAdded()) {
            // pop back stack
            popBackStack();
        }
        mFragmentManager.beginTransaction().replace(containerId, fragment,
                fragment.getClass().getSimpleName()).addToBackStack(null).commit();
    } catch (IllegalStateException e) {
        e.printStackTrace();
        mFragmentManager.beginTransaction().replace(containerId, fragment,
                fragment.getClass().getSimpleName()).addToBackStack(null)
                .commitAllowingStateLoss(); // used as last resort
    }
}
我调用函数的方法是简单地说

addFragmentReplace(R.id.frag_container, new NewsFragment());

我注意到的行为是,当从初始选项卡更改为任何其他选项卡时,我没有收到回调。一旦我返回到最初的选项卡并更改到任何其他选项卡,一切都会正常工作。我试着监控我的备份,以进一步了解可能发生的情况。在我的MainActivity的
onCreate()
方法中,我记录了backbackbackbackcount,结果显示为0,尽管我在第一次启动应用程序后可以清楚地看到游戏片段。当我更改选项卡时,我的backbackbackcount变为1,并且无论由于我的
addFragmentReplace()
方法而更改选项卡多少次,backbackbackbackcount都保持为1。我不确定通过XML添加片段时会发生什么,但我认为这样做可能有问题,或者我的replace函数不正确。提前谢谢

我了解到,如果通过XML添加片段,则无法动态删除/替换它。我通过编程解决了我的问题。首先,在MainActivity中我添加了GameFragment

  @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (!Utils.checkIfNull(findViewById(R.id.frag_container))) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (!Utils.checkIfNull(savedInstanceState)) {
                return;
            }

            addFragment(R.id.frag_container, new GameFragment());
        }

        // initialize views
        initializeViews();
    }
然后,我将XML更改为具有FrameLayout容器,而不是片段容器

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/sky_2"
    tools:context=".activity.MainActivity"
    tools:ignore="UselessParent,contentDescription">

    <FrameLayout
        android:id="@+id/frag_container"
        android:name="com.example.GameFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <include layout="@layout/footer" />
</RelativeLayout>


无法动态删除/替换布局中声明的片段。该事务只是将一个
新闻片段
粘贴在静态
游戏片段
的顶部。哇!我完全没有读到那个细节,但这正是我所经历的。谢谢你让我知道。@Mike M,所以这个帖子有一个可接受的答案。您可以将您的评论作为您的答案,并在其中添加指向引用文档的链接,我将接受您的评论。我通过编程解决了这个问题。很有魅力。哦,很酷。如果你想保留这个问题,我可以找到一个副本。或者,如果你愿意,你可以发布一个答案。我不值得你在文档中无意中错过的东西的任何代表。:-)不过谢谢你。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/sky_2"
    tools:context=".activity.MainActivity"
    tools:ignore="UselessParent,contentDescription">

    <FrameLayout
        android:id="@+id/frag_container"
        android:name="com.example.GameFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <include layout="@layout/footer" />
</RelativeLayout>