Android ViewPager+Fragment(使用问题处理)

本文介绍了解决ViewPager中Fragment的onResume()与onPause()方法在页面切换时的不确定性问题,通过自定义BaseFragment类,实现了Fragment显示时执行onResume(),隐藏时执行onPause()的预期行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ViewPager+Fragment可以非常高效地实现动态编辑多个相似页面。

但是ViewPager会预加载Fragment(左右n(n>=1)个页面) ,导致Fragment的onResume()和onPause()可能不会按预期的执行。在接入友盟统计时,页面统计需要Activity和Fragment的onResume()和onPause()配对,但ViewPager中的Fragment会出现调用顺序问题。

无论如何,对于Fragment,我的期望是显示的时候执行onResume(),隐藏的时候执行onPause()

检测Fragment是否显示有2个方法:

  1. setUserVisibleHint(boolean isVisibleToUser)
  2. getUserVisibleHint()

 ViewPager中的Fragment本身做不到显示的时候执行onResume(),隐藏的时候执行onPause(),所以我要设置方法,让这个方法来做到这样的效果:

    /**
     * 替代具有不确定性的onResume()(ViewPager可能会让多个fragment执行onResume(),但有些fragment执行后是不可见状态的)
     * 我需要的是执行onResume后,确定是可见状态的方法
     */
    protected void onResumeVisible() {}

    /**
     * 替代具有不确定性的onPause()(ViewPager可能会让多个fragment执行onPause())
     * 我需要的是执行onPause前,确定执行onResume()
     */
    protected void onPauseInVisible() {}

 当然,优化Fragment基本考虑到懒加载,顺便实现。全部代码

/**
 * Copyright (C)
 * FileName: BaseFragment
 * Author: wudengwei
 * Date: 2018/12/17 20:15
 * Description: 解决ViewPager中使用显示与隐藏和onResume()与onPause()不一致问题
 */
public class BaseFragment extends Fragment {
    protected Activity mActivity;
    //是否第一次可见
    private boolean isFirstVisible = true;
    //是否可见
    private boolean isVisible = false;
    /**
     * onResume是否已经执行,fragment在ViewPager中
     * 第一次创建时(预加载)不管可不可见,都会执行一次生命周期
     * isFirstOnResume=false表示预加载或当前显示的fragment执行了onResume()
     * isFirstOnResume=false,fragment再次显示时,当做执行了onResume()
     */
    private boolean isFirstOnResume = true;

    /**
     * 作用于onResume()在显示状态下执行后,fragment隐藏时执行对应的onPause()
     * 避免其他页面的onPause()执行
     * 是否可以使用isVisible代替?
     */
    private boolean isOnResumeVisible = false;

    @Override
    public void onAttach(Context context) {
        this.mActivity = (Activity) context;
        super.onAttach(context);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getView() == null)
            return;
        /*可见回调方法*/
        if (isVisible != isVisibleToUser)
            onVisibleChange(isVisibleToUser,isFirstVisible);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        isFirstVisible = true;
        isVisible = false;
        isFirstOnResume = true;
        isOnResumeVisible = false;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (getUserVisibleHint()) {
            /*可见,是否第一次*/
            onVisibleChange(true,isFirstVisible);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isFirstOnResume) {
            isFirstOnResume = false;
        }
        if (getUserVisibleHint() && !isOnResumeVisible) {//onResume()在可见状态下调用
            isOnResumeVisible = true;
            onResumeVisible();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        //onResume()在可见状态下调用后,进入onPause()
        if (!isFirstOnResume && isOnResumeVisible) {
            isOnResumeVisible = false;
            onPauseInVisible();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isFirstVisible = true;
        isVisible = false;
        isFirstOnResume = true;
    }

    /*是否可见回调方法*/
    protected void onVisibleChange(boolean isVisible,boolean firstVisible) {
        this.isVisible = isVisible;
        if (firstVisible) {
            onLazyLoad();
            isFirstVisible = false;
        }
        if (isVisible && !isFirstOnResume && !isOnResumeVisible) {//isFirstOnResume=false表示fragment预加载,onResume()在可见状态下调用
            isOnResumeVisible = true;
            onResumeVisible();
        }
        if (!isVisible && !isFirstOnResume && isOnResumeVisible) {
            isOnResumeVisible = false;
            onPauseInVisible();
        }
    }

    /**
     * 懒加载(第一次可见)
     */
    protected void onLazyLoad() {

    }

    /**
     * 替代具有不确定性的onResume()(ViewPager可能会让多个fragment执行onResume(),但有些fragment执行后是不可见状态的)
     * 我需要的是执行onResume后,确定是可见状态的方法
     */
    protected void onResumeVisible() {}

    /**
     * 替代具有不确定性的onPause()(ViewPager可能会让多个fragment执行onPause())
     * 我需要的是执行onPause前,确定执行onResume()
     */
    protected void onPauseInVisible() {}
}

源码:https://github.com/wudengwei/TabIndicatorLayout

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值