How to determine when Fragment becomes visible in ViewPager

后端 未结 26 1188
心在旅途
心在旅途 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 01:07

    I support SectionsPagerAdapter with child fragments so after a lot of headache I finally got working version based on solutions from this topic:

    public abstract class BaseFragment extends Fragment {
    
        private boolean visible;
        private boolean visibilityHintChanged;
    
        /**
         * Called when the visibility of the fragment changed
         */
        protected void onVisibilityChanged(View view, boolean visible) {
    
        }
    
        private void triggerVisibilityChangedIfNeeded(boolean visible) {
            if (this.visible == visible || getActivity() == null || getView() == null) {
                return;
            }
            this.visible = visible;
            onVisibilityChanged(getView(), visible);
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (!visibilityHintChanged) {
                setUserVisibleHint(false);
            }
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if (getUserVisibleHint() && !isHidden()) {
                triggerVisibilityChangedIfNeeded(true);
            }
        }
    
        @Override
        public void onHiddenChanged(boolean hidden) {
            super.onHiddenChanged(hidden);
            triggerVisibilityChangedIfNeeded(!hidden);
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            visibilityHintChanged = true;
            if (isVisibleToUser && isResumed() && !isHidden()) {
                triggerVisibilityChangedIfNeeded(true);
            } else if (!isVisibleToUser) {
                triggerVisibilityChangedIfNeeded(false);
            }
        }
    
        @Override
        public void onPause() {
            super.onPause();
            triggerVisibilityChangedIfNeeded(false);
        }
    
        @Override
        public void onStop() {
            super.onStop();
            triggerVisibilityChangedIfNeeded(false);
        }
    
        protected boolean isReallyVisible() {
            return visible;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:08

    I encountered this problem when I was trying to get a timer to fire when the fragment in the viewpager was on-screen for the user to see.

    The timer always started just before the fragment was seen by the user. This is because the onResume() method in the fragment is called before we can see the fragment.

    My solution was to do a check in the onResume() method. I wanted to call a certain method 'foo()' when fragment 8 was the view pagers current fragment.

    @Override
    public void onResume() {
        super.onResume();
        if(viewPager.getCurrentItem() == 8){
            foo();
            //Your code here. Executed when fragment is seen by user.
        }
    }
    

    Hope this helps. I've seen this problem pop up a lot. This seems to be the simplest solution I've seen. A lot of others are not compatible with lower APIs etc.

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