可以优化数据加载的时机,尤其是针对网络数据的处理。
可以做到需要是加载,不需要不加载,尤其是针对ViewPager组件,因为其会对其中的fragment进行预加载。
其实核心的就是在恰当的时机去进行数据处理的操作,这个恰当的时机需要满足以下三点:
针对第一点,只需要在onCreateView中,初始化完RootView便可以满足。对于第二点,可以设置一个全局变量mHaveLoadData,初始值为false即可,当加载过数据后再设置为true即可。对于第三点,Fragment提供了一个setUserVisibleHint(boolean isVisibleToUser)方法,通过传入的参数值便可以得知是否对用户可见。对于setUserVisibleHint函数,值得注意的是,这个方法是优于onCreate()方法的,此后当fragment可见性发生变化时还会被调用,所以,这个方法在使用时得配合前两点来进行使用。
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.FrameLayout;
public abstract class BaseLazyFragment extends Fragment {
protected final String TAG = getClass().getSimpleName();
// 表示是否已经请求过数据
public boolean mHaveLoadData = false;
// 表示数据是否已经请求完毕
public boolean mLoadDataFinished = false;
// 表示找控件完成, 给控件们设置数据不会报空指针了
public boolean mViewInflateFinished;
protected FrameLayout mRootView;
protected Context mContext;
protected ViewStub mViewStub;
public BaseLazyFragment() {
}
//是否需要懒加载,默认为是,如果不需要懒加载,可以在子类中重载返回false即可
protected boolean needLazyLoad() {
return true;
}
@Override
public void onAttach(Context context) {
Log.d(TAG, "onAttach");
super.onAttach(context);
this.mContext = context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated");
super.onActivityCreated(savedInstanceState);
if (mRootView != null && getUserVisibleHint() && !mLoadDataFinished) {
viewStubInflater();
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
if (mRootView != null) {
return mRootView;
}
mRootView = new FrameLayout(mContext);
ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.MarginLayoutParams.MATCH_PARENT, ViewGroup.MarginLayoutParams.MATCH_PARENT);
mRootView.setLayoutParams(marginLayoutParams);
mRootView.setBackgroundResource(getBackgroundResource());
//
mViewStub = new ViewStub(mContext, null);
mViewStub.setLayoutResource(getLayoutResId());
FrameLayout.MarginLayoutParams params = new FrameLayout.MarginLayoutParams(FrameLayout.MarginLayoutParams.MATCH_PARENT, FrameLayout.MarginLayoutParams.MATCH_PARENT);
mRootView.addView(mViewStub, params);
return mRootView;
}
protected int getBackgroundResource() {
return android.R.color.transparent;
}
//获取界面LayoutResId
protected abstract int getLayoutResId();
//初始化各个控件
protected abstract void updateView();
//控件初始化完成后加载数据的地方
protected abstract void updateData();
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (!needLazyLoad() && !mHaveLoadData) {
viewStubInflater();
}
}
//视图真正可见的时候才调用
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
//控件用来初始化的地方
if (mRootView != null && needLazyLoad() && isVisibleToUser && !mHaveLoadData) {
viewStubInflater();
}
if (mRootView != null && mViewInflateFinished) {
if (isVisibleToUser) {
visibleToUserLoad();
} else {
inVisibleToUserLoad();
}
}
}
//viewStub加载新布局
protected void viewStubInflater() {
if (mViewStub != null) {
mViewStub.inflate();
}
updateView();
mViewInflateFinished = true;
updateData();
mHaveLoadData = true;
}
//这个是视图在初始化完成后,每次可见时候调用
protected void visibleToUserLoad() {
}
protected void inVisibleToUserLoad() {
}
@Override
public void onDestroyView() {
Log.d(TAG, "onDestroyView");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@Override
public void onDetach() {
Log.d(TAG, "onDetach");
super.onDetach();
}
}