Android开发问题——ViewPager嵌套时Fragment的UserVisibleHint属性不同步

具体问题如下:

现有如下结构:

MainActivity(ViewPager)

  Fragment1

  Fragment2(ViewPager)

    Fragment2-1

    Fragment2-2

  Fragment3

  Fragment4

当我们进入MainActivity的时候,MainActivity的viewpager会进行初始化,初始化完毕之后的状态是

MainActivity(ViewPager)

  Fragment1.UserVisibleHint=true

  Fragment2(ViewPager).UserVisibleHint=false

    Fragment2-1.UserVisibleHint=true

    Fragment2-2.UserVisibleHint=false

  Fragment3.UserVisibleHint=false

  Fragment4.UserVisibleHint=false

可以发现Fragment2的UserVisibleHint为false,而他的第一个子fragment2-1的UserVisibleHint为true

而我们实现懒加载时,需要以UserVisibleHint这个属性来判断是否加载数据,因此当我们进入MainActivity的时候,Fragment1会加载数据,Fragment2-1同样也会加载数据,如何避免Fragment2-1不加载数据呢?因为此时我们只想加载Fragment1的数据。Fragment2-1的UserVisibleHint在我们视觉的真正意义上是false。ViewPager并未提供解决此问题的方法,得靠自己来解决。

先来解决初始化时候让Fragment2-1.UserVisibleHint为false

解决思路就是在子Fragment onAttach的时候检查其父Fragment的mUserVisibleHint属性的状态,如果是false就强制将当前子Fragment的mUserVisibleHint属性设置为false并设置一个恢复标记(因为接下来还需要恢复) 然后在父Fragment setUserVisibleHint为true的时候检查其所有子Fragment,有恢复标记的子Fragment,设置其mUserVisibleHint属性为true,看代码:

public class BaseFragment extends Fragment{
    private boolean waitingShowToUser;
 
    public void onActivityCreated([@Nullable](https://my.oschina.net/u/2896689) Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
 
        // 如果自己是显示状态,但父Fragment却是隐藏状态,就把自己也改为隐藏状态,并且设置一个等待显示标记
        if(getUserVisibleHint()){
            Fragment parentFragment = getParentFragment();
            if(parentFragment != null && !parentFragment.getUserVisibleHint()){
                waitingShowToUser = true;
                super.setUserVisibleHint(false);
            }
        }
    }
 
    [@Override](https://my.oschina.net/u/1162528)
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
 
        if(getActivity() != null) {
            List<Fragment> childFragmentList = getChildFragmentManager().getFragments();
            if (isVisibleToUser) {
                // 将所有正等待显示的子Fragment设置为显示状态,并取消等待显示标记
                if (childFragmentList != null && childFragmentList.size() > 0) {
                    for (Fragment childFragment : childFragmentList) {
                        if (childFragment instanceof BaseFragment) {
                            BaseFragment childBaseFragment = (BaseFragment) childFragment;
                            if (childBaseFragment.isWaitingShowToUser()) {
                                childBaseFragment.setWaitingShowToUser(false);
                                childFragment.setUserVisibleHint(true);
                            }
                        }
                    }
                }
            }
        }
    }
 
    public boolean isWaitingShowToUser() {
        return waitingShowToUser;
    }
 
    public void setWaitingShowToUser(boolean waitingShowToUser) {
        this.waitingShowToUser = waitingShowToUser;
    }
}

接下来解决父ViewPager切换的时候同步其子Fragment的UserVisibleHint属性

思路就是在父Fragment setUserVisibleHint为false的时候将其所有mUserVisibleHint为true的子Fragment都强制改为false,然后设置一个恢复标记,然后在setUserVisibleHint为true的时候再恢复,看代码:

public class BaseFragment extends Fragment{
    private boolean waitingShowToUser;
 
    public void onActivityCreated([@Nullable](https://my.oschina.net/u/2896689) Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
 
        // 如果自己是显示状态,但父Fragment却是隐藏状态,就把自己也改为隐藏状态,并且设置一个等待显示标记
        if(getUserVisibleHint()){
            Fragment parentFragment = getParentFragment();
            if(parentFragment != null && !parentFragment.getUserVisibleHint()){
                waitingShowToUser = true;
                super.setUserVisibleHint(false);
            }
        }
    }
 
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
 
        // 父Fragment还没显示,你着什么急
        if (isVisibleToUser) {
            Fragment parentFragment = getParentFragment();
            if (parentFragment != null && !parentFragment.getUserVisibleHint()) {
                waitingShowToUser = true;
                super.setUserVisibleHint(false);
                return;
            }
        }
 
        if(getActivity() != null) {
            List<Fragment> childFragmentList = getChildFragmentManager().getFragments();
            if (isVisibleToUser) {
                // 将所有正等待显示的子Fragment设置为显示状态,并取消等待显示标记
                if (childFragmentList != null && childFragmentList.size() > 0) {
                    for (Fragment childFragment : childFragmentList) {
                        if (childFragment instanceof BaseFragment) {
                            BaseFragment childBaseFragment = (BaseFragment) childFragment;
                            if (childBaseFragment.isWaitingShowToUser()) {
                                childBaseFragment.setWaitingShowToUser(false);
                                childFragment.setUserVisibleHint(true);
                            }
                        }
                    }
                }
            } else {
                // 将所有正在显示的子Fragment设置为隐藏状态,并设置一个等待显示标记
                if (childFragmentList != null && childFragmentList.size() > 0) {
                    for (Fragment childFragment : childFragmentList) {
                        if (childFragment instanceof BaseFragment) {
                            BaseFragment childBaseFragment = (BaseFragment) childFragment;
                            if (childFragment.getUserVisibleHint()) {
                                childBaseFragment.setWaitingShowToUser(true);
                                childFragment.setUserVisibleHint(false);
                            }
                        }
                    }
                }
            }
        }
    }
 
    public boolean isWaitingShowToUser() {
        return waitingShowToUser;
    }
 
    public void setWaitingShowToUser(boolean waitingShowToUser) {
        this.waitingShowToUser = waitingShowToUser;
    }
}

本文内容来源于:https://blog.csdn.net/didayuye/article/details/101572984

posted @ 2021-04-07 14:30  金大人的梦  阅读(501)  评论(0编辑  收藏  举报