Getting the current Fragment instance in the viewpager

前端 未结 30 1913
醉话见心
醉话见心 2020-11-22 08:56

Below is my code which has 3 Fragment classes each embedded with each of the 3 tabs on ViewPager. I have a menu option. As shown in the onOpt

相关标签:
30条回答
  • 2020-11-22 09:10

    by selecting an option, I need to update the fragment that is currently visible.

    To get a reference to currently visible fragment, assume you have a reference to ViewPager as mPager. Then following steps will get a reference to currentFragment:

    1. PageAdapter adapter = mPager.getAdapter();
    2. int fragmentIndex = mPager.getCurrentItem();
    3. FragmentStatePagerAdapter fspa = (FragmentStatePagerAdapter)adapter;
    4. Fragment currentFragment = fspa.getItem(fragmentIndex);

    The only cast used line 3 is valid usually. FragmentStatePagerAdapter is an useful adapter for a ViewPager.

    0 讨论(0)
  • 2020-11-22 09:10

    When we use the viewPager, a good way to access the fragment instance in activity is instantiateItem(viewpager,index). //index- index of fragment of which you want instance.

    for example I am accessing the fragment instance of 1 index-

    Fragment fragment = (Fragment) viewPageradapter.instantiateItem(viewPager, 1);
    
    if (fragment != null && fragment instanceof MyFragment) {      
     ((MyFragment) fragment).callYourFunction();
    
    }
    
    0 讨论(0)
  • 2020-11-22 09:10

    This is more future-proof than the accepted answer:

    public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
    
        /* ------------------------------------------------------------------------------------------ */
        // region Private attributes :
    
        private Context _context;
        private FragmentManager _fragmentManager;
        private Map<Integer, String> _fragmentsTags = new HashMap<>();
    
        // endregion
        /* ------------------------------------------------------------------------------------------ */
    
    
    
        /* ------------------------------------------------------------------------------------------ */
        // region Constructor :
    
        public MyFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {
    
            super(fragmentManager);
    
            _context = context;
            _fragmentManager = fragmentManager;
        }
    
        // endregion
        /* ------------------------------------------------------------------------------------------ */
    
    
    
        /* ------------------------------------------------------------------------------------------ */
        // region FragmentPagerAdapter methods :
    
        @Override
        public int getCount() { return 2; }
    
        @Override
        public Fragment getItem(int position) {
    
            if(_fragmentsTags.containsKey(position)) {
    
                return _fragmentManager.findFragmentByTag(_fragmentsTags.get(position));
            }
            else {
    
                switch (position) {
    
                    case 0 : { return Fragment.instantiate(_context, Tab1Fragment.class.getName()); }
                    case 1 : { return Fragment.instantiate(_context, Tab2Fragment.class.getName()); }
                }
            }
    
            return null;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
    
            // Instantiate the fragment and get its tag :
            Fragment result = (Fragment) super.instantiateItem(container, position);
            _fragmentsTags.put(position, result.getTag());
    
            return result;
        }
    
        // endregion
        /* ------------------------------------------------------------------------------------------ */
    }
    
    0 讨论(0)
  • 2020-11-22 09:11

    FragmentStatePagerAdapter has a private instance variable called mCurrentPrimaryItem of type Fragment. One can only wonder why Android devs did not supplied it with a getter. This variable is instantiated in setPrimaryItem() method. So, override this method in such a way for you to get the reference to this variable. I simply ended up with declaring my own mCurrentPrimaryItem and copying the contents of setPrimaryItem() to my override.

    In your implementation of FragmentStatePagerAdapter:

    private Fragment mCurrentPrimaryItem = null;
    
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment)object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
                mCurrentPrimaryItem.setUserVisibleHint(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
            }
            mCurrentPrimaryItem = fragment;
        }
    }
    
    public TasksListFragment getCurrentFragment() {
        return (YourFragment) mCurrentPrimaryItem;
    }
    
    0 讨论(0)
  • 2020-11-22 09:11

    You can define the PagerAdapter like this then you will able to get any Fragment in ViewPager.

    private class PagerAdapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragmentList = new ArrayList<>();
    
        public PagerAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }
    
        @Override
        public int getCount() {
            return mFragmentList.size();
        }
    
        public void addFragment(Fragment fragment) {
            mFragmentList.add(fragment);
        }
    }
    

    To get the current Fragment

    Fragment currentFragment = mPagerAdapter.getItem(mViewPager.getCurrentItem());
    
    0 讨论(0)
  • 2020-11-22 09:12

    This is the simplest hack:

    fun getCurrentFragment(): Fragment? {
        return if (count == 0) null
        else instantiateItem(view_pager, view_pager.currentItem) as? Fragment
    }
    

    (kotlin code)

    Just call instantiateItem(viewPager, viewPager.getCurrentItem() and cast it to Fragment. Your item would already be instantiated. To be sure you can add a check for getCount.

    Works with both FragmentPagerAdapter and FragmentStatePagerAdapter!

    0 讨论(0)
提交回复
热议问题