ViewPager 中的片段 returns 空对象 onResume

Fragment in ViewPager returns empty object onResume

我使用 FragmentPagerAdapter 从片段切换。我需要在制作 fragmentswitch 时调用一些函数,并且在使用 OnPause 和 OnResume 时遇到了一些麻烦,所以正如 THIS 问题所建议的那样,我已经实现了一个接口 OnPageSelectListener :

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

只要此页面出现在前台,它就会调用函数 OnPageSelected。工作得很好,除了我想在我的适配器上调用一个函数。我认为这会起作用,除了我的适配器 return 始终为 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 ");
        }
    }

现在我的问题是:当我 return 到我的片段时,为什么 adapter(或片段中的任何其他对象)return 为空?当 fragmentPager 初始化时,片段的 onActivityCreate 函数被调用一次,但之后不再调用,并且适配器 return null....

ViewPager 将在用户更改页面时创建和销毁片段(参见 ViewPager.setOffscreenPageLimit())。因此 onActivityCreated() 仅在片段首次恢复或设置时调用。因此,无需调用 onActivityCreated() 即可创建片段。

而不是 onActivityCreated(),我建议覆盖 onViewCreated() 并在那里设置您的适配器。没有创建视图就无法显示任何片段,因此这是执行此类操作的好地方。

如果您的 OnPageSelectListener 逻辑正常,那很好。我发现了解片段何时实际出现在用户面前的最佳方法是覆盖 FragmentPagerAdapter 中的 setPrimaryItem()。让页面离开视图事件有点棘手,因为您必须保留对前一个 setPrimaryItem() 调用的片段的引用。

您必须在适配器初始化后调用 onPageSelected() 和 setAdapter() 否则适配器将 return 始终为 null

这是因为Viewpager在调用oncreateView()/onActivityCreated()中的Fragments之前调用了OnpageSelected。

最适合您的方法是在 Fragment 的构造函数中扩充视图并设置适配器。

使用成员变量存储Fragment是否激活。并使用 oncreateview() 中的变量调用适配器上的函数。

你为什么不在你的寻呼机中使用 viewpager.addOnPageChangeListener,在你的片段上设置它的适配器和 setOffscreenPageLimit() 而不是 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) {

    }
});

在您的 Activity 中创建它,当然是在您设置 ViewPager 的地方。

这就是我认为您的 CheckListAdapter(我将其称为 listAdapter)为空的原因:

  1. 你把pagerAdapter给了ViewPager
  2. ViewPagerpagerAdapter 询问新的 Fragment
  3. ViewPager 告诉 FragmentManager 使用它
  4. onPageSelected 被调用
  5. 您尝试使用 listAdapter。此时它还没有被初始化。 (NPE)
  6. FragmentManager 将片段拖过所有阶段。
  7. onCreateView 被调用。您的 listAdapter 已创建。

不要尝试使用片段外部的内部数据。它旨在作为一个独立的单元工作,如果您以不同的方式使用它,它不会很好。由于片段是在稍后阶段初始化的,因此您不能按预期使用它。
您可以尝试在片段中做您想做的事情,而不是 pagerAdapter,或者在宿主 Activity 中编写一个方法,并在准备就绪时从片段中调用它,甚至启动一个事件。

对我来说,我不得不在我的 viewpager 上调用它:

myViewPager.setSaveFromParentEnabled(false);