【问题标题】:Previous fragment visible under the new fragment前一个片段在新片段下可见
【发布时间】:2013-05-20 05:32:52
【问题描述】:

我有一个选项卡 + ViewPager 布局,在其中一个选项卡中我有一个列表视图。当我在 onclick 上替换该列表片段时,我仍然可以在新片段下看到旧片段。见:

代码:

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
HallsInStateFragment hallsForState = new HallsInStateFragment();        
transaction.replace(R.id.container, hallsForState);
transaction.addToBackStack(null);
transaction.commit();

R.id.container 是视图中的 FrameLayout。

【问题讨论】:

  • 尝试为包含布局的片段赋予背景颜色
  • 如果您不提供您使用的代码,没有人可以帮助您。另外,请不要在问题标题前加上Android,底部的标签就足够了。
  • 当你应该调用 FragmentTransaction.replace() 时,确保你没有调用 FragmentTransaction.add()。
  • @Krylez 我正在使用 FragmentTransaction.replace()
  • 嗨@SquiresSquire 我面临着同样的问题。你有什么解决办法吗?

标签: android android-actionbar android-viewpager


【解决方案1】:

当需要从父视图中移除所有视图时,您需要在片段的 onCreateView() 方法中的容器中调用 removeAllViews()

代码如下:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

container.removeAllViews(); // Inflate the layout for this fragment
 return inflater.inflate(R.layout.fragment_example, container, false); 
}

【讨论】:

  • 这个问题3年多了,已经解决了
  • 如果我使用 container.removeAllViews();当我从第二个片段按下时,第一个片段将不可见。很显然,它已经被清除了。但是我如何在 backpress 上保留第一个片段,但又如何获得干净的第二个片段?
  • 接受的答案似乎不是有效的函数调用,如果您不依赖回溯历史记录,这将非常有用。事情发生了变化,因此很高兴看到更新的答案,这样我们就不必随着 Android 随着时间的推移而创建重复的问题。谢谢 taranjeetsapra!
【解决方案2】:

而不是 R.id.container 像这样放置片段的 id:((ViewGroup)getView().getParent()).getId()。实际上它不是替换片段而是替换之前的布局,即 FrameLayout。它适用于我,我希望它也适用于你的情况。

【讨论】:

【解决方案3】:

将此添加到两个片段父布局

android:background="@android:color/white"

你正在替换的一个和你将替换的一个。

【讨论】:

  • 这个答案只隐藏了旧片段。使用仍然可以在旧片段中制作点击事件。要禁用此功能,请在根视图中添加`clickable = true`
【解决方案4】:

片段的 UI 是活动视图层次结构的一部分。因此,如果您在 onCreateView() 方法中创建了视图,那么您可以使用 ViewGroup 容器扩展您的布局。此容器保留对您的片段视图的引用。尝试覆盖片段的 onDestroyView() 方法并从父级中删除所有视图:

@Override
public void onDestroyView() {
    //mContainer.removeAllViews();
    ViewGroup mContainer = (ViewGroup) getActivity().findViewById(R.id.container);
    mContainer.removeAllViews();
    super.onDestroyView();
}

【讨论】:

  • Fragment 不应该管理父级,管理其子级是父级的责任。
  • 这对我不起作用,但是@taranjeetsapra 下面的回答似乎到目前为止有效
【解决方案5】:

你的片段应该像这样加载到FrameLayout

    <FrameLayout
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:windowBackground" />

你的片段应该被这个函数添加/加载到这个frameLayout

    private fun switchFragment(
    fragment: Fragment,
    addToBackstack: Boolean
) {
    //check new fragment is alredy loaded currently, then return
    val myFragment =
        supportFragmentManager.fragments.lastOrNull()//return current visible fragment or null
    if (myFragment != null && fragment::class == myFragment::class) {
        return
    }

    val fragmentManager = supportFragmentManager
    val transaction = fragmentManager.beginTransaction()
    //transaction.add(R.id.frameLayout, fragment, fragment.javaClass.name)
    transaction.replace(
        R.id.frameLayout,
        fragment,
        fragment.javaClass.name
    )//using replace will make sure that the previous fragment won't be visible from new fragment
    if (addToBackstack) {
        transaction.addToBackStack(fragment.javaClass.name)
    }
    transaction.commit()
}

所以最初,你的第一个片段应该像这样加载,

switchFragment(HomeFragment(), false)

当你从底部导航视图或导航抽屉中选择其他片段时,像这样调用这个函数

switchFragment(MyProfileFragment(), true)

【讨论】:

    【解决方案6】:

    在根视图中添加 clickable = true 并添加替换当前片段的片段的背景颜色(都在 xml 中)。 它只是解决方法的修复

    【讨论】:

      【解决方案7】:

      最好的代码。显然,没有使用另一台设备。 在您的 Activity onCreate 或添加片段之前添加此代码:

      for (Fragment fragment : getSupportFragmentManager().getFragments()) {
          if (fragment instanceof NavigationDrawerFragment) {
              continue;
          }
          else if (fragment != null) {
              getSupportFragmentManager().beginTransaction().remove(fragment).commit();
          }
      }
      

      编码愉快 :)

      【讨论】:

        【解决方案8】:

        在我的情况下,发生这种情况是因为我使用静态片段作为

            <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
        
        <fragment
            android:name="com.example.android.FooFragment"
            android:id="@+id/fooFragment"
            android:layout_width="match_parent" 
            android:layout_height="match_parent" />
        
        </LinearLayout>
        

        其中 foofragment 是初始片段,然后尝试用其他片段替换片段,使两个片段重叠。

        相反,问题解决了,当我使用动态链接时,代替xml中的片段,我们需要使用framelayout作为

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
        
          <FrameLayout
               android:id="@+id/your_placeholder"
               android:layout_width="match_parent"
               android:layout_height="match_parent">
          </FrameLayout>
        
        </LinearLayout>
        

        然后动态添加 fragment-1 并用 fragment-2 替换,对我来说工作正常。

        I did not find answer earlier, hence posting this solution.
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-07
          相关资源
          最近更新 更多