Android FragmentStatePagerAdapter, how to tag a fragment to find it later

前端 未结 9 1195
独厮守ぢ
独厮守ぢ 2020-12-24 14:09

When using the FragmentStatePageAdapter I get the fragments like this:

    @Override
    public Fragment getItem(int position) {
        return          


        
相关标签:
9条回答
  • 2020-12-24 14:44

    Override setPrimaryItem, and using that position, it would be the right page index:

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
            super.setPrimaryItem(container,position,object);
            if (position == 1) {
                currentPageIndex=cameraFragment.pageIndex;
    }
    
    0 讨论(0)
  • 2020-12-24 14:48

    I implemented this by adding a getItemTag(int position) function to FragmentStatePagerAdapter. A drop-in version of the updated file is here if anyone else wants to go this route.

    0 讨论(0)
  • 2020-12-24 14:49

    Another solution is to copy paste the source code of FragmentStatePagerAdapter and add a getFragment method:

    public Fragment getFragment(int position) {
        if (position >= mFragments.size()) {
            return null;
        }
        return mFragments.get(position);
    }
    
    0 讨论(0)
  • 2020-12-24 14:50

    * EDIT *

    As @ElliotM pointed out, there is a better solution. No need to change anything in your adapter, just get the fragment with:

    Fragment myFragment = (Fragment) adapter.instantiateItem(viewPager, viewPager.getCurrentItem());
    

    * OLD SOLUTION *

    Best option is the second solution here: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html

    In short: you keep track of all the "active" fragment pages. In this case, you keep track of the fragment pages in the FragmentStatePagerAdapter, which is used by the ViewPager..

    public Fragment getItem(int index) {
        Fragment myFragment = MyFragment.newInstance();
        mPageReferenceMap.put(index, myFragment);
        return myFragment;
    }
    

    To avoid keeping a reference to "inactive" fragment pages, we need to implement the FragmentStatePagerAdapter's destroyItem(...) method:

    public void destroyItem(View container, int position, Object object) {
        super.destroyItem(container, position, object);
        mPageReferenceMap.remove(position);
    }
    

    ... and when you need to access the currently visible page, you then call:

    int index = mViewPager.getCurrentItem();
    MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
    MyFragment fragment = adapter.getFragment(index);
    

    ... where the MyAdapter's getFragment(int) method looks like this:

    public MyFragment getFragment(int key) {
        return mPageReferenceMap.get(key);
    }
    

    --- EDIT:

    Also add this in your adapter, for after an orientation change:

    /**
     * After an orientation change, the fragments are saved in the adapter, and
     * I don't want to double save them: I will retrieve them and put them in my
     * list again here.
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        MyFragment fragment = (MyFragment) super.instantiateItem(container,
                position);
        mPageReferenceMap.put(position, fragment);
        return fragment;
    }
    
    0 讨论(0)
  • 2020-12-24 14:56

    I tried Frank's answer that suggests Second Approach from the tutorial linked in it, bot for some reason after adding method getFragment() to my ViewPagerAdapter I can't access it via mViewPager.getAdapter.getFragment() as if it doesn't exist, so I moved mPageReferenceMap declaration from the ViewPagerAdapter to the enclosing class so it is easily accessed from any point of the enclosing class (in my case it is MainActivity's callback method from other fragment) which finally makes it possible to pass data between fragments. Thanks to Frank and feel free to implement my fixture if you like me face issue with accessing custom getFragment method.

    0 讨论(0)
  • 2020-12-24 14:57

    Create a holder to hold the new SuperCoolFragment object. Then tag and return the holder object.

    @Override
    public Fragment getItem(int position) {
        SuperCoolFragment superCoolFragment = new SuperCoolFragment();
        superCoolFragment.setTag(YOUR_TAG);
        return superCoolFragment;
    }
    
    0 讨论(0)
提交回复
热议问题