How to determine when Fragment becomes visible in ViewPager

后端 未结 26 1368
心在旅途
心在旅途 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;
        }
    }
    

提交回复
热议问题