Fragment的生命周期及setuservisiblehint的使用

本文深入探讨了Android中Fragment的生命周期,包括各个状态的转换,并重点讲解了setUserVisibleHint方法的使用场景及其在管理Fragment可见性上的关键作用。通过实例解析,帮助开发者更好地理解和掌握Fragment的生命周期管理。

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

很多应用会使用viewpager+fragment显示自己的内容页,fragment和activity有很多共同点,fragment生命周期依赖于activity,如下图就是fragment的生命周期

但是fragment和activity不同的是当调用本身的onResume和onPause方法的时候可能并不是当前的fragment在显示,例如当加载下面这张图时,当我打开MainActivity时显示的是第一个fragment 但此时调用的方法步骤如下: 

08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-11 11:33:36.159    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated 
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onResume()   可见此时虽然用户看到的是第一个fragment 但第二个fragment onAttech onCreate 
onCreateView onActivityCreater onStart(“这个我没油打印log”)onResume 方法已经调用,这会导致如果我们要统计用户更喜欢哪个fragment的内容时,虽然fragment已经创建并且onResume但其实并没有显示这一页,那么是什么原因呢,这是因为android v4包下的viewpager,为了让用户在切换过程中不会卡顿,谷歌官方默认当创建第一个fragment方法时回创建第二个fragment以确保用户滑动时第二个view已经被创建,保持viewPager的平滑滑动效果。 
翻阅谷歌api发现viewpager有一个方法即 setOffscreenPageLimit。但当在viewpager设置以下代码
viewPager.setOffscreenPageLimit(0);

运行时打印的log和上面完全一致,即就算你设置只加载一个fragment还是会加载第二个fragment,原因是setOffscreenPageLimit中的源码时这样写的 
public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                    DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

这个 DEFAULT_OFFSCREEN_PAGES 定义如下 private static final int DEFAULT_OFFSCREEN_PAGES = 1
就是如果你设置为0 也没用。!!! 
 为了解决判断是否fragment当前显示问题 可以在fragment重写 setUserVisibleHint(boolean isVisibleToUser) 
在fragment添加log日志 
public class Fragment1 extends Fragment {
    private static final String TAG = "Fragment1";

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        L.v(TAG, "onAttach");
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        L.v(TAG, "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        L.v(TAG, "onCreateView");
        View view = inflater.inflate(R.layout.fragment_layout,null);
        TextView tv = (TextView) view.findViewById(R.id.tv1);
        tv.setText(TAG);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        L.v(TAG,"onActivityCreated");
    }

    @Override
    public void onResume() {
        super.onResume();
        L.v(TAG, "onResume()");
    }

    @Override
    public void onPause() {
        super.onPause();
        L.v(TAG,"onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        L.v(TAG,"onStop");
    }
启动activity打印日志如下: 
08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-11 11:33:36.157    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint true
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-11 11:33:36.159    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onResume() 
当切换到第二个activity时打印日志: 
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ setUserVisibleHint false
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint true
08-11 11:33:54.084    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onAttach
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onCreate
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onCreateView
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onActivityCreated
08-11 11:33:54.085    7162-7162/com.example.yinsgo.myui V/Fragment3﹕ onResume() 
可见当fragment显示时回调用方法 setUserVisibleHint中的isVisibleToUser = true 当fragment被切换隐藏时回 isVisibleToUser = false; 
所以当我们要统计是否用户看到一个fragment时可以执行一下代码 
@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        L.v(TAG, "setUserVisibleHint " + isVisibleToUser);
        if (isVisibleToUser) {
            //统计代码 或者 fragment显示操作
        } else {
            
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值