片段 重叠视图



我正在处理片段,但是当我从一个片段切换到另一个视图时出现问题,彼此重叠。

我使用以下代码来切换片段。

getSupportFragmentManager()
.beginTransaction()
.add(R.id.mainContainer, new SecondsFragment())
.addToBackStack(null)
.commit();

我知道使用add()只会在前一个片段的基础上添加更新的片段。我不想使用replace,因为当我使用onBackPress()返回该片段时它会重新加载所有内容,例如,当我使用函数打开第二个片段并返回到第一个片段时,我在第一个片段中有 REST API 调用replace()它将再次调用该 REST API,这对UX不利。

如果我使用add()加载第二个片段,则第二个片段的视图与第一个片段的视图重叠,并且返回第一个片段不调用该 REST API(我想要的行为)。

我也知道,通过设置片段xml父视图的背景,这个问题可以解决,但它也会导致意外点击第一个片段视图再次对UX不利,我也通过在SO中通过将父视图可点击设置为true来阅读这个问题,但正如其他开发人员所说,这只是一个黑客而不是一个正确的解决方案。

我希望像commonsware这样的用户能够解决这个问题。

非常欢迎任何建议/意见。

提前谢谢。

我会尝试一下,我认为您误解了FragmentTransactionadd()的语义,您正在add另一个片段,这应该不会对已经添加的片段产生任何影响。这意味着您的两个片段在FragmentManager状态方面都处于活动状态或RESUMED状态。

事实上,你的第二个片段和你的第一个片段一样大,并且位于它上面,这只是一个只有你关心的实现细节,就FragmentManager而言,你的两个片段都是RESUMED的,活跃的,并且用户难以处理。

基本上,如果add()应该在添加新片段之前以某种方式暂停当前添加的片段,为什么我们需要另一个 API 来replace()

您正在通过滥用其他功能(添加片段)来解决一个问题(不想重新执行网络请求)。

如果希望一次只有一个片段处于活动状态,则需要先删除旧片段,方法是显式调用remove()或通过调用replace()来完成它。

为了避免再次执行网络请求的问题,您可以:

  • 将第一个片段添加到后退堆栈添加中,并使用pop()返回到片段的同一实例,这将需要片段中的一些逻辑来检查某个状态是否未null,然后无需进行网络调用。
  • 将片段的实例手动保存在包含Fragment/Activity中,然后在再次添加旧片段时,添加现有实例,而不是创建一个全新的实例。

但是,如果你的意图确实是让它们都added,但你想限制用户查看/与第一个片段交互的能力,你使用show()hide()这样做。

您可以实例化第一个片段并将其设置为活动片段。选择第二个片段时,隐藏活动片段(片段 1),并将第二个片段设置为活动。

前任。

fragment1 = Fragment1.newInstance();
active = fragment1;
getFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, fragment1, "1")
.commit();

选择第二个片段时,可以执行以下操作:

if (isFirstTimeLoading) {
fragment2 = Fragment2.newInstance();
getFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, fragment2)
.hide(active)
.commit();
active = fragment2;
isFirstTimeLoading = false;
} else {
getFragmentManager()
.beginTransaction()
.hide(active)
.show(fragment2)
.commit();
active = fragment2;
}

最新更新