How to determine when Fragment becomes visible in ViewPager

后端 未结 26 1310
心在旅途
心在旅途 2020-11-22 00:24

Problem: Fragment onResume() in ViewPager is fired before the fragment becomes actually visible.

For example, I have 2 fragments with

相关标签:
26条回答
  • 2020-11-22 00:54

    I overrode the Count method of the associated FragmentStatePagerAdapter and have it return the total count minus the number of pages to hide:

     public class MyAdapter : Android.Support.V13.App.FragmentStatePagerAdapter
     {   
         private List<Fragment> _fragments;
    
         public int TrimmedPages { get; set; }
    
         public MyAdapter(Android.App.FragmentManager fm) : base(fm) { }
    
         public MyAdapter(Android.App.FragmentManager fm, List<Android.App.Fragment> fragments) : base(fm)
         {
             _fragments = fragments;
    
             TrimmedPages = 0;
         }
    
         public override int Count
         {
             //get { return _fragments.Count; }
             get { return _fragments.Count - TrimmedPages; }
         }
     }
    

    So, if there are 3 fragments initially added to the ViewPager, and only the first 2 should be shown until some condition is met, override the page count by setting TrimmedPages to 1 and it should only show the first two pages.

    This works good for pages on the end, but wont really help for ones on the beginning or middle (though there are plenty of ways of doing this).

    0 讨论(0)
  • 2020-11-22 00:55

    How to determine when Fragment becomes visible in ViewPager

    You can do the following by overriding setUserVisibleHint in your Fragment:

    public class MyFragment extends Fragment {
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if (isVisibleToUser) {
            }
            else {
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:57

    Override Fragment.onHiddenChanged() for that.

    public void onHiddenChanged(boolean hidden)

    Called when the hidden state (as returned by isHidden()) of the fragment has changed. Fragments start out not hidden; this will be called whenever the fragment changes state from that.

    Parameters
    hidden - boolean: True if the fragment is now hidden, false if it is not visible.

    0 讨论(0)
  • 2020-11-22 00:57

    Only this worked for me!! and setUserVisibleHint(...) is now deprecated (I attached docs at end), which means any other answer is deprecated ;-)

    public class FragmentFirewall extends Fragment {
        /**
         * Required cause "setMenuVisibility(...)" is not guaranteed to be
         * called after "onResume()" and/or "onCreateView(...)" method.
         */
        protected void didVisibilityChange() {
            Activity activity = getActivity();
            if (isResumed() && isMenuVisible()) {
                // Once resumed and menu is visible, at last
                // our Fragment is really visible to user.
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            didVisibilityChange();
        }
    
        @Override
        public void setMenuVisibility(boolean visible) {
            super.setMenuVisibility(visible);
            didVisibilityChange();
        }
    }
    

    Tested and works with NaviagationDrawer as well, there isMenuVisible() will always return true (and onResume() seems enough, but we want to support ViewPager too).

    setUserVisibleHint is deprecated. If overriding this method, behavior implemented when passing in true should be moved to Fragment.onResume(), and behavior implemented when passing in false should be moved to Fragment.onPause().

    0 讨论(0)
  • 2020-11-22 00:57

    May be very late. This is working for me. I slightly updated the code from @Gobar and @kris Solutions. We have to update the code in our PagerAdapter.

    setPrimaryItem is called every time when a tab is visible and returns its position. If the position are same means we are unmoved. If position changed and current position is not our clicked tab set as -1.

    private int mCurrentPosition = -1;
    
    @Override
    public void setPrimaryItem(@NotNull ViewGroup container, int position, @NotNull Object object) {
        // This is what calls setMenuVisibility() on the fragments
        super.setPrimaryItem(container, position, object);
        if (position == mCurrentPosition) {
            return;
        }
        if (object instanceof YourFragment) {
            YourFragment fragment = (YourFragment) object;
            if (fragment.isResumed()) {
                mCurrentPosition = position;
                fragment.doYourWork();//Update your function
            }
        } else {
            mCurrentPosition = -1;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:59

    Here is another way using onPageChangeListener:

      ViewPager pager = (ViewPager) findByViewId(R.id.viewpager);
      FragmentPagerAdapter adapter = new FragmentPageAdapter(getFragmentManager);
      pager.setAdapter(adapter);
      pager.setOnPageChangeListener(new OnPageChangeListener() {
    
      public void onPageSelected(int pageNumber) {
        // Just define a callback method in your fragment and call it like this! 
        adapter.getItem(pageNumber).imVisible();
    
      }
    
      public void onPageScrolled(int arg0, float arg1, int arg2) {
        // TODO Auto-generated method stub
    
      }
    
      public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub
    
      }
    });
    
    0 讨论(0)
提交回复
热议问题