zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

android Fragment单页面加载,避免重复加载(懒加载)分析

2023-03-07 09:08:12 时间

上面两个页面都是 ViewPager + Fragment实现,Viewpager + Fragment情况下,fragment的生命周期因Viewpager的缓存机制而失去了具体意义

目前问题:每次进入4个Fragment的生命周期都会走一遍,数据同时请求,这就会造成UI初始化较慢

需求:每次进入只加载当前看到界面数据、切换时请求当前选项卡数据、重复切换只加载一次

具体实现原理:

使用Fragment类自带方法setUserVisibleHint()判断当前fragment是否对用户可见,根据回调的isVisibleToUser参数来进行相关的逻辑判断。重写该方法,创建变量isVisible拿到是否可见标志。

但是直接根据isVisible判断就加载数据,可能onCreateView()方法并未执行完毕,此时就会出现NullPointerException空指针异常。所以就需要满足控件初始化完成,用户可见,才能加载数据。

为了方便继承调用,将实现封装到了BaseFragment中

package com.jky.mobilebzt.fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.Toast;


public  class BaseNewFragment extends Fragment {

	private static final String TAG = BaseFragment.class.getSimpleName();

	private boolean isFragmentVisible;
	private boolean isReuseView;
	private boolean isFirstVisible;
	private View rootView;
	public Context context;

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		//setUserVisibleHint()有可能在fragment的生命周期外被调用
		if (rootView == null) {
			return;
		}
		if (isFirstVisible && isVisibleToUser) {
			onFragmentFirstVisible();
			isFirstVisible = false;
		}
		if (isVisibleToUser) {
			onFragmentVisibleChange(true);
			isFragmentVisible = true;
			return;
		}
		if (isFragmentVisible) {
			isFragmentVisible = false;
			onFragmentVisibleChange(false);
		}
	}

	@Override
	public void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light);
		initVariable();
	}

	@Override
	public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
		if (rootView == null) {
			rootView = view;
			if (getUserVisibleHint()) {
				if (isFirstVisible) {
					onFragmentFirstVisible();
					isFirstVisible = false;
				}
				onFragmentVisibleChange(true);
				isFragmentVisible = true;
			}
		}
		super.onViewCreated(isReuseView ? rootView : view, savedInstanceState);
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		initVariable();
	}

	private void initVariable() {
		isFirstVisible = true;
		isFragmentVisible = false;
		rootView = null;
		isReuseView = true;
	}


	private Toast toast;

	public void showShortToast(String text) {
		if (!TextUtils.isEmpty(text)) {
			if (toast != null) {
				toast.cancel();
				toast = null;
			}
			if(getActivity()!=null){
				toast = Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT);
				toast.show();
			}
		}
	}

	protected void reuseView(boolean isReuse) {
		isReuseView = isReuse;
	}

	protected void onFragmentVisibleChange(boolean isVisible) {

	}

	protected void onFragmentFirstVisible() {

	}

	protected boolean isFragmentVisible() {
		return isFragmentVisible;
	}
}

 在fragment中继承BaseFragment并实现两个方法 onFragmentVisibleChange 和onFragmentFirstVisible

	@Override
	protected void onFragmentVisibleChange(boolean isVisible) {
	}

	@Override
	protected void onFragmentFirstVisible() {
    //这里面写请求数据的方法
		PAGE_INDEX = 1;
		getData(0);
	}