我正在处理片段,但是当我从一个片段切换到另一个视图时彼此重叠时会出现问题。
我正在使用以下代码来切换片段。
getSupportFragmentManager()
.beginTransaction()
.add(R.id.mainContainer, new SecondsFragment())
.addToBackStack(null)
.commit();
我知道使用add()
只会在前一个片段上添加更新的片段。我不想使用replace
因为当我使用onBackPress()
返回到该片段时重新加载所有内容,例如当我使用replace()
函数打开第二个片段时,我在第一个片段中有REST API调用并返回到第一个片段它将再次调用REST API,这对UX
不利。
如果我使用add()
加载第二个片段,则第二个片段的视图与第一个片段的视图重叠,并返回到第一个片段,而不是调用REST API (我想要的行为)。
我也知道通过设置片段xml父视图的背景,这个问题可以解决,但是它也会导致意外点击第一个片段视图再次对UX
不利,我也读到 SO 通过将父视图设置为clickable也将解决此问题,但正如其他开发人员所说,这只是一个黑客而不是一个合适的解决方案。
我希望像 commonsware 这样的用户能够解决这个问题。
非常欢迎任何建议/意见。
先谢谢。
答案 0 :(得分:1)
我试着尝试一下,我认为你错过了add()
中FragmentTransaction
的语义,是你是add
另一个片段,这不应该对已经添加的片段产生任何影响。这意味着您的两个片段都处于有效状态,或者RESUMED
状态为FragmentManager
。
你的第二个片段和你的第一个片段一样大,并且位于它之上的事实仅仅是你所关注的实现细节,就FragmentManager
而言,你的片段都是RESUMED
,由用户激活且难以处理。
基本上,如果add()
在添加新片段之前应以某种方式暂停当前添加的片段,为什么我们需要replace()
的其他API
您正在通过滥用其他功能(添加片段)修复一个问题(不想重新执行网络请求)。
如果您希望一次只激活一个片段,则需要首先删除旧片段,方法是显式调用remove()
或者通过调用{{1 }}
为避免再次发出网络请求的问题,您可以:
replace()
返回到片段的同一个实例,这将需要片段中的一些逻辑来检查某个状态是否不是{{1然后,无需进行网络通话。pop()
/ null
的内容中手动保存片段实例,然后在再次添加旧片段时添加现有实例,而不是创建全新的实例。 但是,如果你的意图确实是让他们两个Fragment
,但你想限制用户查看/与第一个片段互动的能力,那么你可以使用Activity
,added
这样做。
答案 1 :(得分:0)
您可以实例化第一个片段并将其设置为活动片段。选择第二个片段时,隐藏活动片段(片段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;
}