繁体   English   中英

导航回 FragmentPagerAdapter -> 片段为空

[英]Navigating back to FragmentPagerAdapter -> fragments are empty

我有一个 Fragment(我称之为pagerFragment ),它被添加到 backstack 并且是可见的。 它拥有一个带有FragmentPagerAdapterviewPager FragmentPagerAdapter包含(假设)两个片段:A 和 B。

首先添加片段效果很好。

片段 A 有一个按钮,单击该按钮后,会将片段 (C) 添加到 backstack。

问题是这样的:如果我添加那个片段(C),然后点击返回, pagerAdapter是空的,我看不到里面的任何片段。

如果我使用 hack 并销毁pagerFragment s onDestroyView()的子片段(A 和 B onDestroyView() ,这可以解决问题,尽管我不想使用此 hack。

任何想法可能是什么问题?

我有同样的问题。 我的解决方案很简单:

在 onCreateView 我有:

// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity()
    .getSupportFragmentManager());

其中 SectionPageAdapter 是这样的:

class SectionsPagerAdapter extends FragmentPagerAdapter {
...
}

将 getSupportFragmentManager 更改为

mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());

它开始工作了! 希望这可以帮助。

听起来您正在使用嵌套片段,因为您的 ViewPager 位于 PagerFragment 内。 您是否已将 getChildFragmentManager() 传递给 FragmentPagerAdapter 的构造函数? 如果不是,你应该。

我认为您不需要 FragmentStatePagerAdapter,但我会尝试一下,因为它可以处理保存和恢复 Fragment 状态。 您的 onDestroyView() hack 有效这一事实让我认为您可能需要 FragmentStatePagerAdapter。

它还可能与 FragmentPagerAdapter 添加 Fragments 的方式有关。 FragmentPagerAdapter 不会将 Fragments 添加到 backstack。 想象一下,如果您在 ViewPager 中添加了 10 多个页面并且用户在它们之间滑动。 用户需要回击 11 次才能退出应用程序。

也可能与这篇文章有关: Nested Fragments and The Back Stack

另外,我不确定您要将片段 C 添加到什么中。 您是否将其添加到与 ViewPager 相同的容器中?

好吧,至少你有几个选择来调查。 在这些情况下,我喜欢调试到 Android SDK 源代码中,看看是什么导致了这种行为。 我建议获取AOSP 源并添加 frameworks/support 和 frameworks/base 作为您的 SDK 源。 这是了解正在发生的事情并避免在一切正常之前进行随机更改的唯一正确方法。

使用getChildFragmentManager()而不是getSupportFragmentManager() 它会正常工作。

我刚刚在我们的项目中也遇到了这个问题。 根本原因是 FragmentPagerAdapter 的工作方式:

FragmentPagerAdapter 只是将他当前不需要的 Fragment 从其 View 中分离,但不会将其从其 FragmentManager 中移除。 当他想再次显示 Fragment 时,他会使用从 ViewPager 的视图 ID 和适配器 getItemId(position) 调用返回的 ID 创建的标记来查看 FragmentManager 是否仍包含 Fragment。 如果他找到一个 Fragment,他只需在 FragmentManager 的更新事务中安排将 Fragment 附加到其视图。 只有当他没有以这种方式找到 Fragment 时,他才会使用适配器 getItem(position) 调用创建一个新的 Fragment!

包含带有 FragmentPagerAdapter 的 ViewPager 的 Fragment 的问题是,当包含的 Fragment 被放入后堆栈时,永远不会清除 FragmentManager 的内容。 如果包含 Fragment 从返回堆栈返回,它会创建一个新视图,但 FragmentManager 仍然包含附加到旧视图的片段,并且现有片段的附加不再起作用。

摆脱这个问题的最简单方法是避免嵌套片段。 :)

第二种最简单的方法是在其他帖子中已经提到,将 ChildFragmentManager 用于 FragmentPagerAdapter,因为这个方法在容器片段的生命周期中得到正确更新。

由于有些项目(作为我当前的项目)无法使用这两个选项,因此我在此处发布了一个解决方案,该解决方案可与任意 FragmentManager 一起使用,方法是使用子片段的 hashCode 作为该位置片段的项目 ID。 它的代价是存储适配器内所有位置的所有片段。

public class MyPagerAdapter extends FragmentPagerAdapter {

private static int COUNT = ...;
private final FragmentManager fragmentManager;
private Fragment[] subFragments = new Fragment[COUNT];
private FragmentTransaction cleanupTransaction;

public MyPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
    this.fragmentManager = fragmentManager;
}

@Override
public Fragment getItem(int position) {
    return getSubFragmentAtPosition(position);
}

@Override
public int getCount() {
    return COUNT;
}

@Override
public long getItemId(int position) {
    return getSubFragmentAtPosition(position).hashCode();
}

//The next three methods are needed to remove fragments no longer used from the fragment manager
@Override
public void startUpdate(ViewGroup container) {
    super.startUpdate(container);
    cleanupTransaction = fragmentManager.beginTransaction();
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    cleanupTransaction.remove((Fragment) object);
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
    cleanupTransaction.commit();
}

private Fragment getSubFragmentAtPosition(int position){
    if (subFragments[position] == null){
        subFragments[position] = ...;
    }
    return subFragments[position];
}

}

我有同样的问题,只需一次设置适配器两次仅此而已。

示例代码:

 private fun displayImg(photo1:String, photo2:String){ val pager:ViewPager = v?.findViewById(R.id.ProductImgPager)!! val arr = ArrayList<String>() arr.add(photo1) arr.add(photo2) pager.adapter = AdapterImageView(fm, arr ,arr.size) pager.adapter = AdapterImageView(fm, arr ,arr.size) }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM