判断当前界面是该fragment_在使用Fragment过程中遇到的坑(一)切换判断界面是否可见,关于onhiddenchanged和setUserVisibleHint函数...

本文详细讨论了在使用Fragment时如何判断界面可见性以实现懒加载。在ViewPager中通常使用setUserVisibleHint()方法,但在自定义FragmentTransaction操作时,此方法可能不被调用,这时可以借助onHiddenChanged()。文章通过代码示例解释了这两个方法的使用场景,并提供了BaseFragment和LazyFragment的封装示例,以应对不同的懒加载需求。
摘要由CSDN通过智能技术生成

背景:项目中每个页面多个地方使用到Fragment,有的是在viewpager中,有的自己进行管理;项目运行一段时间后想对fragment进行懒加载处理,很早之前只对ViewPager中的Fragment进行过处理,结果在处理过程中遇到的一些问题。

先看一段代码

public abstract class BaseFragment extends Fragment {

private boolean isFirstVisible = true;

private boolean isFirstInvisible = true;

private boolean isViewCreated;

private boolean isUIVisible;

@Override

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

isViewCreated = true;

lazyLoad(); // 执行懒加载,因为无法确定setUserVisibleHint和onViewCreated哪个方法先执行,因此两个方法里面都需要调用lazyLoad

}

@Override

public void setUserVisibleHint(boolean isVisibleToUser) {

super.setUserVisibleHint(isVisibleToUser);

if (isVisibleToUser) {

isUIVisible = true; //当前fragment可见

if (isFirstVisible) {

//如果是第一次可见,则进行懒加载

isFirstVisible = false;

lazyLoad();

} else {

//不是第一次可见,则调用onUserVisible()

onUserVisible();

}

} else {

isUIVisible = false;

if (isFirstInvisible) {

isFirstInvisible = false;

//第一次不可见

onFirstUserInvisible();

} else {

//非第一次不可见

onUserInvisible();

}

}

}

private void lazyLoad() {

if (isViewCreated && isUIVisible) { //需要进行双重判断,避免因为setUserVisibleHint先于onViewCreaetd调用时,出现空指针

LogUtils.e( this.getClass().getSimpleName() + "lazyLoad");

// initViewsAndEvents();

onFirstUserVisible(); //进行初次可见时的加载

}else {

LogUtils.e( this.getClass().getSimpleName() + ">>>>isViewCreated:" + isViewCreated + "------>>>>>isUIVisible:" + isUIVisible);

}

}

protected abstract void onFirstUserVisible();

protected abstract void onUserVisible();

protected abstract void onFirstUserInvisible();

protected abstract void onUserInvisible();

}

一般ViewPager+Fragment的时候,主要使用到了setUserVisibleHint()方法进行判断Fragment是否可见,来进行懒加载处理。

但是

但是

但是

在某些场景中setUserVisibleHint()竟然没有执行~~~~:在未使用Viewpager,而是自己通过FragmentTransaction 对Fragment进行add hide show操作,setUserVisibleHint()方法没有被调用。原因是hide()和show()方法调用时,Fragment不走任何的生命周期。

这时候突然发现另外一个Fragment方法onhiddenchanged(),该方法用于判断fragment显隐,正好切合hide show操作。

public abstract class LazyFragment extends BaseFragment {

public static final String TAG = LazyFragment.class.getSimpleName();

private boolean hasLoaded = false;

private boolean isCreated = false;

private boolean isVisibleToUser = false;

private View view;

@Override

protected void initViews(View view, @Nullable Bundle savedInstanceState) {

isCreated = true;

this.view = view;

lazyLoad(this.view, savedInstanceState);

}

@Override

public void setUserVisibleHint(boolean isVisibleToUser) {

this.isVisibleToUser = isVisibleToUser;//注:关键步骤

super.setUserVisibleHint(isVisibleToUser);

lazyLoad(view, null);

}

private void lazyLoad(View view, Bundle savedInstanceState) {

if (!isVisibleToUser || hasLoaded || !isCreated) {

return;

}

lazyInitView(view, savedInstanceState);

hasLoaded = true;//注:关键步骤,确保数据只加载一次

}

public abstract void lazyInitView(View view, Bundle savedInstanceState);

@Override

public void onDestroyView() {

super.onDestroyView();

isCreated = false;

hasLoaded = false;

}

}

然后对BaseFragment进行进一步封装,应对各种情况。

总结

onhiddenchanged()

用FragmentTransaction来控制fragment的hide和show时,那么这个方法就会被调用。每当你对某个Fragment使用hide或者是show的时候,那么这个Fragment就会自动调用这个方法。

(使用情况:你自己去管理Fragment,而不是用viewpager管理的时候)

setUserVisibleHin()

在使用viewpager的时候,viewpager内部有个提前缓存的机制(默认是提前缓存一页),比如你在看第一个Fragment的时候,隔壁的Fragment已经创建好了,但此时的状态却是不可见的。

但是这时候Fragment不会去调用上面说的onhiddenchanged方法,只会调用setUserVisibleHint这个方法。

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值