How can i set a tag for viewpager fragments?

前端 未结 3 1209
再見小時候
再見小時候 2020-12-31 01:41

I,m using slidingTabLayout with 4 tabs and a viewpager and 4 fragment class for every tab.

i need to reload one of my fragments (first tab) in my project when user

相关标签:
3条回答
  • 2020-12-31 02:25

    There are couple of solution for this.

    1). When the FragmentPagerAdapter adds a Fragment to the FragmentManager, it uses a special tag based on the particular position that the Fragment will be placed. So you can simply get the current visible Fragment in your ViewPager using these lines of code

     Fragment fragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
     // based on the current position you can then cast the page to the correct Fragment class and call some method inside that fragment to reload the data:
     if (0 == ViewPager.getCurrentItem() && null != fragment) {
          ((TabFragment1)fragment).reloadFragmentData();     
     } 
    

    2). You should keep track of all the active fragments in the FragmentStatePagerAdapter. For demo sample you can refer to second approach here

    3). You can make use of EventBus to post events to your Fragment from anywhere. All you have to do is to register your Fragment for that specific event. For official documentation refer this

    0 讨论(0)
  • 2020-12-31 02:28

    Here is the method which is used by FragmentPagerAdapter to create the Fragment's tag name:

    private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }
    

    viewId is the id of the ViewPager.
    id is the position of the fragment inside the ViewPager.

    Example:

    String fragmentTag = makeFragmentName(myViewPager.getId(), 2);
    Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
    
    0 讨论(0)
  • 2020-12-31 02:28

    Though this question has already been answered. I have another approach for achiving this and this might be better one as the way fragments are tagged in the code are subjected to change. Also to point out using adapter.getItem(position) does not return the instance of fragment being displayed, it will depend on our own implementation of getItem method.

    So Basically the problem is that we do not have the instance of Fragments that are present in the viewPager. The idea is to override method

    public Object instantiateItem(ViewGroup container, int position) {
        // If we already have this item instantiated, there is nothing
        // to do.  This can happen when we are restoring the entire pager
        // from its saved state, where the fragment manager has already
        // taken care of restoring the fragments we previously had instantiated.
        if (mFragments.size() > position) {
            Fragment f = mFragments.get(position);
            if (f != null) {
                return f;
            }
        }
    
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
    
        Fragment fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
        if (mSavedState.size() > position) {
            Fragment.SavedState fss = mSavedState.get(position);
            if (fss != null) {
                fragment.setInitialSavedState(fss);
            }
        }
        while (mFragments.size() <= position) {
            mFragments.add(null);
        }
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);
        mFragments.set(position, fragment);
        mCurTransaction.add(container.getId(), fragment);
    
        return fragment;
    }
    

    of FragmentStatePagerAdapter. If we look at the default implementation of this method, it basically does the job of instantiating new Fragments if they do not exists and returning them. Also it stores them in a list of fragments which is private. So what we can do is Override this method and store the instances on fragments in our own list. This can be implemented in the following way

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    
        private ArrayList<Fragment> fragmentList;
    
        private final int NUM_PAGES;
    
        public ScreenSlidePagerAdapter(FragmentManager fm, int numPages) {
            super(fm);
            NUM_PAGES = numPages;
            fragmentList = new ArrayList<>(NUM_PAGES);
        }
    
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = new CustomFragment();
            //this method can be modified according to the requirement
            return fragment;
        }
    
        @Override
        public int getCount() {
            return NUM_PAGES;
        }
    
        public Fragment getFragment(int position){
            return fragmentList.get(position);
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position){
            Fragment fragment = (Fragment) super.instantiateItem(container,position);
            if(fragmentList.size()<NUM_PAGES&&!fragmentList.contains(fragment)){
                fragmentList.add(fragment);
            }
            return fragment;
        }
    }
    

    Therefore we will have the instances of all the fragments available with us we would no longer need any tags to find the fragment instances being displayed to the user.

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