0

My solution for loading data when fragment visible using setUserVisibleHint

If you using ViewPager to host Fragment and you only want to load data when you come to this Fragment, you can do like

 public abstract class FragmentHelpLoadDataWhenVisible extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,Bundle savedInstanceState) {
            if(getUserVisibleHint()){ // fragment is visible
                loadData();
            }
            return super.onCreateView(inflater, container, savedInstanceState);
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if (isVisibleToUser && isResumed()) { // fragment is visible and have created
                loadData();
            }
        }
    
        public void loadData(){
            // data for fragment when it visible here
        }
    }

You need loadData() inside both setUserVisibleHint and onCreateView because setUserVisibleHint can call before onCreateView so if we just always loadData() inside setUserVisibleHint, we can get NullPointerException

For example, my viewpager have 3 tabs (Tab1, Tab2, Tab3).
At first time I go to this viewpager, the function will call in order like

Tab1 => setUserVisibleHint (isVisibleToUser = false) (isResumed = false)
Tab2 => setUserVisibleHint (isVisibleToUser = false) (isResumed = false)
Tab1 => setUserVisibleHint (isVisibleToUser = true) (isResumed = false)
Tab1 => onCreateView (getUserVisibleHint() = true)
Tab2 => onCreateView (getUserVisibleHint() = false)

At this case, loadData() get called inside onCreateView of Tab1 (we will not get any NullPointerException)

Then I go to Tab2, the the function will call in order like

Tab3 => setUserVisibleHint (isVisibleToUser = false) (isResumed = false)
Tab1 => setUserVisibleHint (isVisibleToUser = false) (isResumed = true)
Tab2 => setUserVisibleHint (isVisibleToUser = true) (isResumed = true)
Tab3 => onCreateView (getUserVisibleHint() = false)

At this case loadData() get called inside setUserVisibleHint of Tab2 like we expected Hope it help


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí