Getting the current Fragment instance in the viewpager

前端 未结 30 1914
醉话见心
醉话见心 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:12

    If your pager is inside a Fragment then use this:

    private fun getPagerCurrentFragment(): Fragment? {
        return childFragmentManager.findFragmentByTag("android:switcher:${R.id.myViewPagerId}:${myViewPager.currentItem}")
    }
    

    Where R.id.myViewPagerId is the id of your ViewPager inside the xml Layout.

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

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

    A simple way of doing this is using a trick related to the FragmentPagerAdapter implementation:

    case R.id.addText:
         Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
         // based on the current position you can then cast the page to the correct 
         // class and call the method:
         if (ViewPager.getCurrentItem() == 0 && page != null) {
              ((FragmentClass1)page).updateList("new item");     
         } 
    return true;
    

    Please rethink your variable naming convention, using as the variable name the name of the class is very confusing(so no ViewPager ViewPager, use ViewPager mPager for example).

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

    First of all 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.

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

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

    @Override
    public void destroyItem (ViewGroup 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);
    }
    

    Hope it may help!

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

    There are a lot of answers here that don't really address the basic fact that there's really NO WAY to do this predictably, and in a way that doesn't result you shooting yourself in the foot at some point in the future.

    FragmentStatePagerAdapter is the only class that knows how to reliably access the fragments that are tracked by the FragmentManager - any attempt to try and guess the fragment's id or tag is not reliable, long-term. And attempts to track the instances manually will likely not work well when state is saved/restored, because FragmentStatePagerAdapter may well not call the callbacks when it restores the state.

    About the only thing that I've been able to make work is copying the code for FragmentStatePagerAdapter and adding a method that returns the fragment, given a position (mFragments.get(pos)). Note that this method assumes that the fragment is actually available (i.e. it was visible at some point).

    If you're particularly adventurous, you can use reflection to access the elements of the private mFragments list, but then we're back to square one (the name of the list is not guaranteed to stay the same).

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

    This is the only way I don't get NullPointerException for the instance variables of that particular fragment classes. This might be helpful for others who stuck at the same thing. In the onOptionsItemSelected(), I coded the below way:

    if(viewPager.getCurrentItem() == 0) {
        FragmentClass1 frag1 = (FragmentClass1)viewPager
                                .getAdapter()
                                .instantiateItem(viewPager, viewPager.getCurrentItem());
        frag1.updateList(text); 
    } else if(viewPager.getCurrentItem() == 1) {
        FragmentClass2 frag2 = (FragRecentApps)viewPager
                                .getAdapter()
                                .instantiateItem(viewPager, viewPager.getCurrentItem());
        frag2.updateList(text);
    }
    
    0 讨论(0)
  • 2020-11-22 09:20

    Current Fragment:

    This works if you created a project with the fragments tabbar template.

    Fragment f = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
    

    Note that this works with the default tabbed activity template implementation.

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