结合Fragment + ViewPager以及Fragment + FrameLayout(add + attach + detach),整理出如下:BaseFragment
package com.jingtuo.android.app.compat.pro.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.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
/**
* Fragment-基类
*
* 经过分析Fragment+ViewPager的Fragment的生命周期,不建议Fragment+ViewPager嵌套Fragment+ViewPager,因为会预加载嵌套内的不可见Fragment
*
* @author JingTuo
*/
public class BaseFragment extends Fragment {
private final String TAG;
public BaseFragment() {
TAG = getClass().getSimpleName();
}
private boolean userVisible = false;
private boolean containerIsViewPager = false;
private boolean resume = false;
private BaseFragment parentFragment;
private boolean show = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.i(TAG, "onAttach");
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
containerIsViewPager = container instanceof ViewPager;
return inflater.inflate(onCreateLayoutId(), container, false);
}
protected int onCreateLayoutId() {
return -1;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i(TAG, "onViewCreated");
}
@Override
public void onAttachFragment(Fragment childFragment) {
super.onAttachFragment(childFragment);
//当出现Fragment嵌套Fragment时,需要额外处理
//当前的fragment已经onResume
//childFragment刚刚被attach,还没有没有执行onCreate、onViewCreated、onResume
//在此处设置ParentFragment状态,在childFragment的onResume方法中拦截判断是否是真正显示
Log.i(TAG, "onAttachFragment: " + childFragment.getClass().getSimpleName());
if (childFragment instanceof BaseFragment) {
((BaseFragment) childFragment).setParentFragment(this);
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.i(TAG, "onStart");
}
/**
* Fragment + ViewPager必然触发setUserVisibleHint
* 首次创建的Fragment
* 显示的Fragment: setUserVisibleHint(false)->setUserVisibleHint(true)->onResume
* 预加载的Fragment: setUserVisibleHint(false)->onResume->setUserVisibleHint(true)
* @param isVisibleToUser
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Log.i(TAG, "setUserVisibleHint: " + isVisibleToUser);
boolean flag = !userVisible && !isVisibleToUser || userVisible && isVisibleToUser;
if (flag) {
//状态未发生变化,忽略
return;
}
if (parentIsShow()) {
//没有在Fragment中或者父Fragment的容器已经显示
if (isVisibleToUser) {
if (resume) {
//resume是false时,view还没有创建不进行预加载处理
onShow();
}
} else {
onHide();
}
}
//父Fragment没有显示时,触发此方法属于预加载,预加载过程中,先setUserVisibleHint,后onResume,在onResume中触发onPreload
userVisible = isVisibleToUser;
}
@Override
public void onResume() {
super.onResume();
resume = true;
Log.i(TAG, "onResume: parent show: " + parentIsShow());
Log.i(TAG, "onResume: " + containerIsViewPager + ", " + userVisible);
if (parentIsShow()) {
//没有在Fragment中或者父Fragment的容器已经显示
if (containerIsViewPager) {
if (userVisible) {
//userVisible为false时,是预加载,在setUserVisibleHint处理真正的显示
onShow();
} else {
onPreload();
}
} else {
onShow();
}
} else {
//父Fragment没有显示,是预加载
onPreload();
}
}
/**
* 真正显示
*/
public void onShow() {
show = true;
Log.i(TAG, "onShow");
List<Fragment> fragments = getChildFragmentManager().getFragments();
for (Fragment fragment: fragments) {
if (fragment instanceof BaseFragment) {
BaseFragment baseFragment = (BaseFragment) fragment;
Log.i(TAG, "child fragment " + baseFragment.getClass().getSimpleName() + ": " + baseFragment.containerIsViewPager + "," + baseFragment.isUserVisible() + "," + baseFragment.isResume());
if (baseFragment.containerIsViewPager) {
if (baseFragment.userVisible && baseFragment.resume) {
baseFragment.onShow();
}
} else {
if (baseFragment.resume) {
baseFragment.onShow();
}
}
}
}
}
/**
* 真正隐藏
*/
public void onHide() {
show = false;
Log.i(TAG, "onHide");
List<Fragment> fragments = getChildFragmentManager().getFragments();
for (Fragment fragment: fragments) {
if (fragment instanceof BaseFragment) {
BaseFragment baseFragment = (BaseFragment) fragment;
Log.i(TAG, "child fragment " + baseFragment.show);
//每次只有一个子Fragment显示,只需要将当前显示的hide即可
if (baseFragment.show) {
baseFragment.onHide();
}
}
}
}
/**
* 预加载
*/
public void onPreload() {
Log.i(TAG, "onPreload");
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
Log.i(TAG, "onHiddenChanged: " + hidden);
}
@Override
public void onPause() {
super.onPause();
resume = false;
Log.i(TAG, "onPause");
if (containerIsViewPager) {
//真正隐藏地方在setUserVisibleHint(false)
} else {
onHide();
}
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.i(TAG, "onDetach");
if (parentFragment != null) {
parentFragment = null;
}
}
public boolean isUserVisible() {
return userVisible;
}
public boolean isResume() {
return resume;
}
public void setParentFragment(BaseFragment parentFragment) {
this.parentFragment = parentFragment;
}
/**
* 判断父Fragment是否显示
* @return
*/
public boolean parentIsShow() {
if (parentFragment == null) {
//当没有父Fragment,认为是显示
return true;
}
//判断父Fragment是否显示&&父Fragment的父Fragment是否显示
return parentFragment.show && parentFragment.parentIsShow();
}
}
来源:oschina
链接:https://my.oschina.net/u/219974/blog/4475892