ViewPager中的Fragment在onResume时返回空对象

6

我使用 FragmentPagerAdapter 来切换片段。当进行片段切换时,我需要调用一些函数,并且在 OnPause 和 OnResume 中遇到了一些麻烦,所以根据 问题的建议,我实现了一个 OnPageSelectListener 接口:

public interface OnPageSelectListener {
    void onPageSelected();
    void onPageNotVisible();
}

每当该页面进入前台时,它都会调用OnPageSelected函数。这很好,但我想在我的适配器上调用一个函数。我认为这应该可以工作,但是我的适配器始终返回NULL(即使它已初始化并按照我的喜好加载了列表视图中的数据)。

    public class AfterCheckFragment extends Fragment implements OnPageSelectListener{


        private   ListView listView;
        private List<Check> checkList;
        private CheckListAdapter adapter;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_check, container, false);

        System.out.println("VIEW create  called");

//(.. some other stuff, not relevant for question..)

        //initializing the adapter
          listView = (ListView) view.findViewById(R.id.listView);
        adapter = new CheckListAdapter(checkList,getActivity(),trainPosition);

        listView.setAdapter(adapter);
        adapter.handleButtonVisibility();
        return view;

    }
@Override
    public void onPageSelected() {
        if(this.adapter != null) {
            System.out.println("adapter not null");
            this.adapter.checkForActive();
        }else{
            System.out.println("Adapter is NULL");
        }

    }

        @Override
        public void onPageNotVisible() { //page is moved to backgroung
            System.out.println("AFTER not active any more ");
        }
    }

现在我的问题是:为什么当我返回到我的碎片时,适配器(或碎片中的任何其他对象)返回null?当fragmentPager被初始化时,片段的onActivityCreate函数被调用一次,但之后没有了,适配器返回null....

界面需要在片段(AfterCheckFragment)和继承的接口之间进行数据通信,但我没有看到它。有时片段会调用接口中的公共/受保护方法,但我没有看到。请至少发布OnPageSelectListener的代码,也许还有相关的适配器。 - The Original Android
请附上适配器代码,因为您已编写了this.adapter.checkForActive() 且您说“为什么adapter会返回空值…”? - The Original Android
我刚刚注意到你发布的代码根本没有显示FragmentPagerAdapter。我之所以这么说是因为该类有其自己的在片段之间切换的方式,相关链接@http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html。我认为引用FragmentPagerAdapter的代码也可能是相关的。 - The Original Android
6个回答

3

在初始化适配器和设置适配器之后,您必须调用onPageSelected(),否则适配器将始终返回null。


2
会在用户切换页面时创建和销毁片段(请参见)。 因此,当恢复或首次设置片段时才调用。因此,可以创建片段而从未调用。
建议覆盖而不是,并在那里设置适配器。没有视图创建就无法显示任何片段,因此这是做这种事情的好地方。
如果您的逻辑正在工作,则很好。我发现了解何时实际上将片段放在用户前面的最佳方法是通过在中覆盖。将页面移出视图事件有点棘手,因为您必须保留对先前调用中片段的引用。

嗨Kris,谢谢你的回答。我按照你的建议在onViewCreated中实现了初始化(尽管我以前使用onActivityCreated从未遇到过问题),但是只有在创建viewpager时才会调用onViewCreate。而且每次返回到视图时,pager仍然返回null。 - Jasper
能否请您贴出更多的代码?我做了一个类似你的测试应用,没有遇到任何问题。第二页的视图在用户浏览第一页时被创建在屏幕外,所以当用户滚动并调用OnPageChangeListener.onPageSelected(2)时,视图已经被创建,所以...没有问题。 - kris larson

2
这是我认为你的CheckListAdapter(我将其称为listAdapter)为空的原因:
  1. 您将

    pagerAdapter给了ViewPager

  2. ViewPager请求pagerAdapter获得新的Fragment
  3. ViewPager告诉FragmentManager使用它
  4. 调用onPageSelected
  5. 您尝试使用listAdapter,但此时它尚未初始化(NPE)
  6. FragmentManager通过所有阶段拖动Fragment。
  7. 调用onCreateView。创建您的listAdapter
不要尝试在片段之外使用片段的内部数据。它旨在作为一个独立的单元运作,在使用不同的方式时效果不佳。由于片段在较晚的阶段初始化,您无法像打算的那样使用它。
您可以尝试在片段中执行想要做的操作,而不是在pagerAdapter中执行,或者在托管Activity中编写一个方法,并在就绪时从片段中调用它,甚至启动一个事件。

1
对于我来说,我必须在我的ViewPager上调用这个:
myViewPager.setSaveFromParentEnabled(false);

1
这是因为Viewpager在调用oncreateView()/onActivityCreated()之前就会调用OnpageSelected。
对您来说,最好的方式是在Fragment的构造函数中填充视图并设置适配器。
或者
使用成员变量来存储Fragment是否处于活动状态,并在oncreateview()中使用该变量调用适配器上的函数。

1
为什么不在设置适配器和 setOffscreenPageLimit() 后,在你的页面上使用 viewpager.addOnPageChangeListener,而不是在你的 fragment 上 implements 它呢?
这里有一个示例代码:
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
       if(position == 1){  // if you want the second page, for example
           //Your code here
       }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
});

在您设置ViewPagerActivity中进行操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接