片段重叠视图

时间:2017-12-07 10:30:30

标签: android android-fragments

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

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

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 这样的用户能够解决这个问题。

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

先谢谢。

2 个答案:

答案 0 :(得分:1)

我试着尝试一下,我认为你错过了add()FragmentTransaction的语义,是你是add另一个片段,这不应该对已经添加的片段产生任何影响。这意味着您的两个片段都处于有效状态,或者RESUMED状态为FragmentManager

你的第二个片段和你的第一个片段一样大,并且位于它之上的事实仅仅是你所关注的实现细节,就FragmentManager而言,你的片段都是RESUMED,由用户激活且难以处理。

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

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

如果您希望一次只激活一个片段,则需要首先删除旧片段,方法是显式调用remove()或者通过调用{{1 }}

为避免再次发出网络请求的问题,您可以:

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

但是,如果你的意图确实是让他们两个Fragment,但你想限制用户查看/与第一个片段互动的能力,那么你可以使用Activityadded这样做。

答案 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;
 }