java - 嵌套 ViewPager 旋转后返回 null

标签 java android android-fragments android-viewpager

我需要在 PageFragSanningellerKonsekvens 中引用 VerticalViewPager

我有两个 ViewPager:一个用于永远持续的水平滑动,另一个用于加载三个加载内容的 fragment (中间、向上滑动、向下滑动)的垂直滑动。水平 ViewPager 在每次滑动时加载 VerticalViewPager 的新实例。我需要在由 VerticalViewPager 加载的实际 fragment 中引用,以便我可以通过点击按钮垂直滑动。我还需要对水平 ViewPager 的引用,以允许第一页有一个触发水平滑动的按钮。

我通过将引用作为参数发送来解决这个问题,如下所示:

FragSanningEllerKonsekvens - 初始化 VerticalViewPager 的类。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_sanning_eller_konsekvens, container, false);
    initComponents();
    setComponents();
    return view;
}

private void initComponents() {
    verticalViewPager = (VerticalViewPager) view.findViewById(R.id.verticalviewpager);
    mStatementPagerAdapter = new TruthDarePagerAdapter(getChildFragmentManager()).newInstance(getChildFragmentManager(),mViewPager, verticalViewPager);
}

它在TruthOrDarePagerAdapter中的传输:

private ViewPager mViewPager;
private VerticalViewPager mVerticalViewPager;
public static TruthDarePagerAdapter newInstance(FragmentManager fm, ViewPager mViewPager, VerticalViewPager mVerticalViewPager){
    TruthDarePagerAdapter horizontalPagerAdapter = new TruthDarePagerAdapter(fm);
    horizontalPagerAdapter.setViewPager(mViewPager);
    horizontalPagerAdapter.setVerticalViewPager(mVerticalViewPager);
    return horizontalPagerAdapter;
}


public VerticalViewPager getVerticalViewPager() {
    return mVerticalViewPager;
}

public void setVerticalViewPager(VerticalViewPager mVerticalViewPager) {
    this.mVerticalViewPager = mVerticalViewPager;
}

private void setViewPager(ViewPager mvViewPager){
    this.mViewPager = mvViewPager;
}

private ViewPager getViewPager(){
    return mViewPager;
}

@Override
public Fragment getItem(int position) {
    PageFragSanningellerKonsekvens frag = new PageFragSanningellerKonsekvens().newInstance(getViewPager(), getVerticalViewPager());
.
.
.
    return frag;
}

PageFragSanningellerKonsekvens - 需要引用的类。

public static PageFragSanningellerKonsekvens newInstance(ViewPager mViewPager, VerticalViewPager mVerticalViewPager){
    PageFragSanningellerKonsekvens frag = new PageFragSanningellerKonsekvens();
    frag.setViewPager(mViewPager);
    frag.setVerticalViewPager(mVerticalViewPager);
    return frag;
}


private void setupMenu() {


    viewTop = view.findViewById(R.id.sek_top);
    viewBottom = view.findViewById(R.id.sek_bottom);

    viewTop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getVerticalViewPager().setCurrentItem(0, true);
        }
    });

    viewBottom.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getVerticalViewPager().setCurrentItem(2, true);
        }
    });
}

在我旋转设备之前,上面的代码工作得很好。旋转后,getVerticalViewPager() 返回null在应用程序的其他部分,我使用了这种模式,没有任何问题:在旋转时,ViewPager 作为参数发送,并且应用程序重新加载而不会删除引用。

所以我得出的结论是,VerticalViewPager 不会在旋转时重新初始化,而 PageFragSanningellerKonsekvens 则会。

我的问题是;我该如何解决它?我可以强制它重新初始化,或者我可以通过其他方式获取对它的引用吗?

编辑1:我认为它与FragmentStatePagerAdapter中的getItem()相关。它将在每个给定时间被调用来分配 3 个 fragment 。我认为这可能会使 getVerticalViewPager() 方法无效。

编辑2:我移动了一些代码以允许ViewPager和按钮在同一个类中初始化,从而使其在某种程度上是防空的。感谢您的帮助!

最佳答案

好吧,这可能不是一个完整的答案,但我认为评论太长了。

我认为你是对的,空指针发生在适配器中的 getItem 处。 (一个 logcat 报告来确认这一点会很好)。 其原因(我认为)是适配器尝试在 ViewPager 的膨胀完成之前重新创建内部 fragment 。通常我在 onCreate 中创建类似的适配器,因为它通常不依赖于除了fragmentmanager 之外的任何东西。

考虑到这一点,以及您可能很难避免当前设计中的空指针这一事实,我提出了一种新设计。

我现在只有手机,所以很难给你我想要的代码。现在我只是勾勒出这个想法:

  • 将 ViewPagers 的 getter/setter 从适配器移至 FragSanningEllerKonsekvens,使 TruthOrDarePagerAdapter 的创建仅依赖于 fragment 管理器

  • 现在对 PageFragSanningellerKonsekvens 执行相同的操作,使其仅在适配器的 getItem 中使用 PageFragSanningellerKonsekvens.newInstance()

  • 最后,您现在缺少对 PageFragSanningellerKonsekvens 中的 ViewPagers 的引用 PageFragSanningellerKonsekvens,但请记住,您现在在父 FragSanningEllerKonsekvens 中拥有两个 ViewPagers 的 getter

所以按钮现在变成:

((FragSanningEllerKonsekvens)getParentFragment()).getVerticalViewPager().setCurrentItem(0, true);

还有

((FragSanningEllerKonsekvens)getParentFragment()).getVerticalViewPager().setCurrentItem(2, true);

关于java - 嵌套 ViewPager 旋转后返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27585913/

相关文章:

java - 单向链表中的分区

java - 重音字符需要多一个字符

java - Android 按钮在运行 AsyncTask 后消失

java - Android中线程的合理使用

java - 使用抽屉导航时尝试从空对象引用的字段 'int android.support.v4.app.Fragment.mContainerId' 读取

android - fragment 列表和 BackStackEntry 动态

java - 如何将 oracle.sql.ARRAY 转换为任何 java 集合(例如,转换为 java 列表或任何)

java - 安卓/Java : Is there a way to call the return of the method after a listener triggered?

java - 如何更改ListView项的文本背景

android - 为什么我需要按两次后退按钮才能在第一次关闭 fragment ?