嵌套的ViewPager在旋转后返回null

时间:2014-12-21 01:17:42

标签: java android android-fragments android-viewpager

我需要在VerticalViewPager中引用PageFragSanningellerKonsekvens

我有两个ViewPagers:一个用于水平滑动,一直持续,一个用于垂直滑动,加载三个碎片(中间,向上滑动,向下滑动),加载内容。水平ViewPager会在每次滑动时加载VerticalViewPager的新实例。我需要VerticalViewPager加载的实际片段中的引用,以便我可以通过点击按钮垂直滑动。我还需要对水平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}}。

我的问题是;我怎么解决呢?我可以强制它重新初始化,还是可以通过其他方式获取它的引用?

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

编辑2:我移动了一些代码以允许ViewPager和按钮在同一个类中初始化,从而使其有点无效。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

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

我认为你是对的,空指针发生在适配器的getItem中。 (一个logcat报告,以确认这将是不错的)。 这个(我认为)的原因是适配器尝试在ViewPager的通胀完成之前重新创建内部片段。通常我在onCreate中创建类似的适配器,因为它通常不依赖于片段管理器以外的任何东西。

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

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

  • 将ViewPagers的getter / setter从适配器移动到FragSanningEllerKonsekvens,让TruthOrDarePagerAdapter的创建仅依赖于片段管理器

  • 现在对PageFragSanningellerKonsekvens做同样的事情,在适配器的getItem中简单地使用PageFragSanningellerKonsekvens.newInstance()

  • 最后,您现在错过了PageFragSanningellerKonsekvens PageFragSanningellerKonsekvens中对ViewPagers的引用,但请记住,您现在在父FragSanningEllerKonsekvens

  • 中有两个ViewPagers的getterrs

现在按钮变为:

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

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