Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewPager Fragments are not initiated in onCreate

I seem to be having an issue updating the fragments that I am using in my ViewPager, regardless of whether I try in onCreate(), onCreateView(), or onResume(). Here is how I'm setting up my ViewPager in my MainFragment:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       View rootView = inflater.inflate(R.layout.fragment_main_screen, container, false);

        mPager = (ViewPager)rootView.findViewById(R.id.pager);
        mPager.setOffscreenPageLimit(2); // So all 3 pages are loaded at once.
        mAdapter = new JournalPagerAdapter(getActivity().getSupportFragmentManager(), this);
        mPager.setAdapter(mAdapter);

        // Add bar graph to view
        mGraphLayout = (LinearLayout) rootView.findViewById(R.id.journalGraph);
        updateGraph();
        mGraphLayout.addView(mGraphView);

        mPainFrag = (PainFragment)mAdapter.getRegisteredFragment(0);
        // Null pointer here, but if I put the action in a button listener, it works.
        mPainFrag.setScale(mEntry.getPain());
...

I'm accessing the fragments through some overridden methods in my FragmentPagerAdapter:

public class JournalPagerAdapter extends FragmentPagerAdapter {

    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    private View.OnClickListener mOnClickListener;


    public JournalPagerAdapter(FragmentManager mgr, View.OnClickListener onClickListener) {
        super(mgr);
        mOnClickListener = onClickListener;
    }
    @Override
    public Fragment getItem(int pos) {
        switch(pos) {

            case 0: return PainFragment.newInstance("PainFragment", mOnClickListener);
            case 1: return StressFragment.newInstance("StressFragment", mOnClickListener);
            case 2: return SleepFragment.newInstance("SleepFragment", mOnClickListener);
            default: return PainFragment.newInstance("PainFragment", mOnClickListener);
        }
    }

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

    /* Thanks to Streets of Boston (http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager)
    */

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.v("rx", "itemInstantiated");
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

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

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }

I can't seem to figure out why the fragment is null right after I set the adapter, but if I put the fragment update code in a click event, I have no issues.

like image 396
jwBurnside Avatar asked Apr 10 '14 19:04

jwBurnside


Video Answer


1 Answers

I would try adding a layout listener to your ViewPager to get notified when the laying out of views has occurred.

When you create your ViewPager call mPager.getViewTreeObserver().addOnGlobalLayoutListener() and pass something implementing OnGlobalLayoutListener.

In the callback method, do your fragment updating. Make sure to call mPager.getViewTreeObserver().removeGlobalOnLayoutListener(this) in the callback, otherwise the callback will be called multiple times.

like image 66
dandc87 Avatar answered Nov 13 '22 07:11

dandc87