在FrameLayout中切换视图(膨胀片段)时发生问题

时间:2017-02-12 08:09:38

标签: android fragment android-framelayout

我的问题如下:

我有一个应用程序有一个主要活动,其中有 是一个frameLayout容器(containerViewId),用于在菜单导航器选择时显示/膨胀不同的片段。

我实际上做的是在onCreate()活动上创建所有片段对象并将其添加到frameLayout:

伪代码:

//在主要活动中     的onCreate()

Fragment1 fragment_1 = new Fragment1();

Fragment2 fragment_2 = new Fragment2()

Fragment3 fragment_3 = new Fragment3()

fragmentTransaction.add(containerViewId, fragment_1, "frag_1");
fragmentTransaction.add(containerViewId, fragment_2, "frag_2");
fragmentTransaction.add(containerViewId, fragment_3, "frag_3");

// hide fragments 2&3, so only fragment_1 is showed

fragmentTransaction.hide(fragment_2);

fragmentTransaction.hide(fragment_3);

.commit()..

现在,当用户从导航视图中选择特定选项时,我就是这样 隐藏显示的当前片段,并显示如下所示的片段(例如从fragment_1切换到fragment_2):

 fragmentTransaction.hide(fragment_1);

 fragmentTransaction.show(fragment_2);

 fragmentTransaction.commit();

一切都按预期工作(片段成功切换),但我有时观察到一段时间后(当我将我的应用从背景带到前面时),之前的片段突然显示/重叠在一起(即使我总是隐藏当前片段片段并显示下一个)

我错过了什么吗? 为什么突然显示我之前的观点?

谢谢: - )

2 个答案:

答案 0 :(得分:1)

您需要替换而不是堆叠片段。如果您希望能够导航回上一个片段,请使用addToBackStack

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

fragmentmanager上有一些方法可以从backstack获取或弹出以前的片段:popBackStack(),getBackStackEntryAt(int index)等等。

<强>更新

方法popBackStack弹出backstack的顶部。靠背包含BackStackEntries。 Backstack条目仅包含片段的一些引用字段。您应该将片段作为变量保存在包含的类中,以便可以替换它们。请注意,您应始终实施适当的生命周期管理,因为在Android中,如果您在后台拥有数据,则无法确定数据是否仍在内存中。

以下是有关活动生命周期的一些信息,但对于片段,它们大致相同:

  

当您的活动在之前被销毁之后重新创建时,您   可以从系统通过的Bundle恢复已保存的状态   你的活动。 onCreate()和onRestoreInstanceState()   回调方法接收包含实例的相同Bundle   国家信息。

     

因为无论系统是否正在创建,都会调用onCreate()方法   您必须在活动的新实例或重新创建前一个实例   在尝试读取之前检查状态Bundle是否为null。   如果为null,则系统正在创建新的实例   活动,而不是恢复之前被破坏的活动。

有关片段生命周期的一些官方文档:https://developer.android.com/guide/components/fragments.html#Lifecycle

答案 1 :(得分:0)

保持简单。做这样的事情 -

    Fragment1 fragment_1 = new Fragment1();
    Fragment2 fragment_2 = new Fragment2();
    Fragment3 fragment_3 = new Fragment3();

    fragmentTransaction.replace(containerViewId, fragment_1, "frag_1"); //when you want show fragment 1
    fragmentTransaction.commit();

//similarly just replace with fragment2 and fragment 3 when you want to show them respectively.The trick is to replace (which internally removes all previously added fragments before adding the current fragment, thus no overlapping issues)