Retrieve a Fragment from a ViewPager

前端 未结 23 2515
逝去的感伤
逝去的感伤 2020-11-21 11:13

I\'m using a ViewPager together with a FragmentStatePagerAdapter to host three different fragments:

  • [Fragment1]
  • [Fragment2]<
相关标签:
23条回答
  • 2020-11-21 11:42

    Another simple solution:

        public class MyPagerAdapter extends FragmentPagerAdapter {
            private Fragment mCurrentFragment;
    
            public Fragment getCurrentFragment() {
                return mCurrentFragment;
            }
    //...    
            @Override
            public void setPrimaryItem(ViewGroup container, int position, Object object) {
                if (getCurrentFragment() != object) {
                    mCurrentFragment = ((Fragment) object);
                }
                super.setPrimaryItem(container, position, object);
            }
        }
    
    0 讨论(0)
  • 2020-11-21 11:43

    Create integer resource id in /values/integers.xml

    <integer name="page1">1</integer>
    <integer name="page2">2</integer>
    <integer name="page3">3</integer>
    

    Then in PagerAdapter getItem function:

    public Fragment getItem(int position) {
    
            Fragment fragment = null;
    
            if (position == 0) {
                fragment = FragmentOne.newInstance();
                mViewPager.setTag(R.integer.page1,fragment);
    
            }
            else if (position == 1) {
    
                fragment = FragmentTwo.newInstance();
                mViewPager.setTag(R.integer.page2,fragment);
    
            } else if (position == 2) {
    
                fragment = FragmentThree.newInstance();
                mViewPager.setTag(R.integer.page3,fragment);
    
            }
    
            return fragment;
            }
    

    Then in activity write this function to get fragment reference:

    private Fragment getFragmentByPosition(int position) {
        Fragment fragment = null;
    
        switch (position) {
            case 0:
                fragment = (Fragment) mViewPager.getTag(R.integer.page1);
                break;
    
            case 1:
    
                fragment = (Fragment) mViewPager.getTag(R.integer.page2);
                break;
    
            case 2:
                fragment = (Fragment) mViewPager.getTag(R.integer.page3);
                break;
                }
    
                return fragment;
        }
    

    Get the fragment reference by calling the above function and then cast it to your custom fragment:

    Fragment fragment = getFragmentByPosition(position);
    
            if (fragment != null) {
                        FragmentOne fragmentOne = (FragmentOne) fragment;
                        }
    
    0 讨论(0)
  • 2020-11-21 11:44

    I know this has a few answers, but maybe this will help someone. I have used a relatively simple solution when I needed to get a Fragment from my ViewPager. In your Activity or Fragment holding the ViewPager, you can use this code to cycle through every Fragment it holds.

    FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
    for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
        Fragment viewPagerFragment = fragmentPagerAdapter.getItem(i);
        if(viewPagerFragment != null) {
            // Do something with your Fragment
            // Check viewPagerFragment.isResumed() if you intend on interacting with any views.
        }
    }
    
    • If you know the position of your Fragment in the ViewPager, you can just call getItem(knownPosition).

    • If you don't know the position of your Fragment in the ViewPager, you can have your children Fragments implement an interface with a method like getUniqueId(), and use that to differentiate them. Or you can cycle through all Fragments and check the class type, such as if(viewPagerFragment instanceof FragmentClassYouWant)

    !!! EDIT !!!

    I have discovered that getItem only gets called by a FragmentPagerAdapter when each Fragment needs to be created the first time, after that, it appears the the Fragments are recycled using the FragmentManager. This way, many implementations of FragmentPagerAdapter create new Fragments in getItem. Using my above method, this means we will create new Fragments each time getItem is called as we go through all the items in the FragmentPagerAdapter. Due to this, I have found a better approach, using the FragmentManager to get each Fragment instead (using the accepted answer). This is a more complete solution, and has been working well for me.

    FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
    for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
        String name = makeFragmentName(mViewPager.getId(), i);
        Fragment viewPagerFragment = getChildFragmentManager().findFragmentByTag(name);
        // OR Fragment viewPagerFragment = getFragmentManager().findFragmentByTag(name);
        if(viewPagerFragment != null) {
    
            // Do something with your Fragment
            if (viewPagerFragment.isResumed()) {
                // Interact with any views/data that must be alive
            }
            else {
                // Flag something for update later, when this viewPagerFragment
                // returns to onResume
            }
        }
    }
    

    And you will need this method.

    private static String makeFragmentName(int viewId, int position) {
        return "android:switcher:" + viewId + ":" + position;
    }
    
    0 讨论(0)
  • 2020-11-21 11:44

    in TabLayout there are multiple tab for Fragment. you can find the fragment by Tag using the index of the fragment.

    For ex. the index for Fragment1 is 0, so in findFragmentByTag() method, pass the tag for the Viewpager.after using fragmentTransaction you can add,replace the fragment.

    String tag = "android:switcher:" + R.id.viewPager + ":" + 0; Fragment1 f = (Fragment1) getSupportFragmentManager().findFragmentByTag(tag);

    0 讨论(0)
  • 2020-11-21 11:46

    You don't need to call getItem() or some other method at later stage to get the reference of a Fragment hosted inside ViewPager. If you want to update some data inside Fragment then use this approach: Update ViewPager dynamically?

    Key is to set new data inside Adaper and call notifyDataSetChanged() which in turn will call getItemPosition(), passing you a reference of your Fragment and giving you a chance to update it. All other ways require you to keep reference to yourself or some other hack which is not a good solution.

    @Override
    public int getItemPosition(Object object) {
        if (object instanceof UpdateableFragment) {
            ((UpdateableFragment) object).update(xyzData);
        }
        //don't return POSITION_NONE, avoid fragment recreation. 
        return super.getItemPosition(object);
    }
    
    0 讨论(0)
  • 2020-11-21 11:46
    Fragment yourFragment = yourviewpageradapter.getItem(int index);
    

    index is the place of fragment in adapter like you added fragment1 first so retreive fragment1 pass index as 0 and so on for rest

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