1 之前使用Fragment懒一般使用fragment.getUserVisibleHint来判断是否已经显示,今天来说一个更简便的方式:
FragmentPagerAdapter支持两种方式,一种是默认设置setUserVisibleHint,另外一种则是使用mCurTransaction.setMaxLifecycle来控制。
//FragmentPagerAdapter源码如下:
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
} else {
fragment.setUserVisibleHint(false);
}
今天说是第二种方式:
FragmentViewPagerAdapter mAdapter = new FragmentViewPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
这样的话可以直接在fragment里的onResume()生命周期中加载数据,比如
@Override
public void onResume() {
super.onResume();
Logger.d(TAG, "onResume");
if (!isLoaded) {
initData();
}
}
数据加载成功后,isLoaded设置为true即可,完全不用当心onResume()方法调用问题!
2 原理:
重点在FragmentManagerImpl中的代码:
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
newState取最小值,默认是Lifecycle.State.RESUMED(相当于全生命周期),如果你自己设置值,则会按照你设置的周期走,而不是每次都走完整的生命周期!
PS:
f.mMaxState.ordinal()是指枚举的顺序,Lifecycle生命周期对应如下5个:
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
RTED,
RESUMED;
}
Fragment的周期对应如下:
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.