Fragment(碎片)在Activity中的使用是非常频繁的,Activity使用Fragment主要有直接通过FragmentManager添加到Activity视图中,或者通过ViewPager加入多个Fragment,通常为了用户体验保存隐藏Fragment的状态,我们都是通过FragmentManager.hide和show方法进行切换Fragment的或者ViewPager.setOffscreenPageLimit()不销毁隐藏的Fragment,这样会导致不显示的Fragmnent也会执行onResume和onPause方法,下面我测试了一下不同方式添加Fragment的结果:
测试的Fragmnet:
public class TestFragment extends Fragment {
private static final String TAG = "TestFragment";
protected String mName;
public static TestFragment create(String mName) {
TestFragment fragment = new TestFragment();
fragment.mName = mName;
return fragment;
}
public void setName(String mName) {
this.mName = mName;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
TextView view = new TextView(getContext());
view.setText(mName);
return view;
}
@Override
public void onResume() {
Log.e(TAG, mName + "==>onResume,isHidden=" + isHidden() + ",getUserVisibleHint=" + getUserVisibleHint());
super.onResume();
}
@Override
public void onPause() {
Log.e(TAG, mName + "==>onPause,isHidden=" + isHidden() + ",getUserVisibleHint=" + getUserVisibleHint());
super.onPause();
}
@Override
public void onHiddenChanged(boolean hidden) {
Log.e(TAG, mName + "==>onHiddenChanged,isHidden=" + hidden + ",getUserVisibleHint=" + getUserVisibleHint());
super.onHiddenChanged(hidden);
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.e(TAG, mName + "==>setUserVisibleHint,isHidden=" + isHidden() + ",getUserVisibleHint=" + isVisibleToUser);
super.setUserVisibleHint(isVisibleToUser);
}
}
在Activity-Fragments,Fragment进行切换并退出的log:
在Activity-ViewPager-Fragments初始化log:
ViewPager进行切换并退出的log:
Activity-Fragment-ViewPager-Fragments初始化log:
ViewPager切换并退出log:
由测试得出不同点:
1、通过FragmentManager添加的Fragment在切换时会调用onHiddenChanged(boolean hidden)其中getUserVisibleHint()是一直true
2、ViewPager添加的Fragment切换时会调用setUserVisibleHint(boolean isVisibleToUser)其中isHidden()一直未false,而且初始化时我们设置了setOffscreenPageLimit(3),导致全部Fragment都初始化了
相同点:Fragment的onResume和onPause都会随Activity的onResume和onPause一起被调用
现在根据测试结果改一下TestFragment:
public class TestFragment extends Fragment {
private static final String TAG = "TestFragment";
protected String mName;
private boolean isPageResume;
public static TestFragment create(String mName) {
TestFragment fragment = new TestFragment();
fragment.mName = mName;
return fragment;
}
public void setName(String mName) {
this.mName = mName;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
TextView view = new TextView(getContext());
view.setText(mName);
return view;
}
@Override
public void onResume() {
Log.e(TAG, mName + "==>onResume,isHidden=" + isHidden() + ",getUserVisibleHint=" + getUserVisibleHint());
if (!isPageResume && !isHidden() && getUserVisibleHint()) {
onPageResume();
}
super.onResume();
}
@Override
public void onPause() {
Log.e(TAG, mName + "==>onPause,isHidden=" + isHidden() + ",getUserVisibleHint=" + getUserVisibleHint());
if (isPageResume) {
onPagePause();
}
super.onPause();
}
@Override
public void onHiddenChanged(boolean hidden) {
Log.e(TAG, mName + "==>onHiddenChanged,isHidden=" + hidden + ",getUserVisibleHint=" + getUserVisibleHint());
if (hidden) {
if (isPageResume && getUserVisibleHint()) {
onPagePause();
}
} else {
if (!isPageResume && getUserVisibleHint()) {
onPageResume();
}
}
super.onHiddenChanged(hidden);
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.e(TAG, mName + "==>setUserVisibleHint,isHidden=" + isHidden() + ",getUserVisibleHint=" + isVisibleToUser);
if (isVisibleToUser) {
if (!isPageResume && !isHidden()) {
onPageResume();
}
} else {
if (isPageResume && !isHidden()) {
onPagePause();
}
}
super.setUserVisibleHint(isVisibleToUser);
}
protected void onPageResume() {
Log.e(TAG, mName + "==>onPageResume");
isPageResume = true;
}
protected void onPagePause() {
Log.e(TAG, mName + "==>onPagePause");
isPageResume = false;
}
}
这样就可以像使用Activity的onResume和onPause那样使用TestFragment的onPageResume()和onPagePause()方法。