很久没有写博客了,今天学习了MD的TabLayout ,使用到了ViewPager,于是对于很久以来的一个疑问:ViewPager切换Fragment生命周期是如何变化的进行了一个测试。
本文研究了:
1. ViewPager2个相邻Fragment之间的切换生命周期变化
2. ViewPager间隔3个Fragment之间的切换生命周期变化
3. ViewPager间隔4个Fragment之间的切换生命周期变化
如果看过类似文章请自行跳过。
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
.support.v4.view.ViewPager
android:id="@+id/vp_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
.support.v4.view.ViewPager>
.support.design.widget.TabLayout
android:id="@+id/tl_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
.support.design.widget.TabLayout>
package tyh.com.tablayout;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class MainActivity extends AppCompatActivity {
@InjectView(R.id.vp_content)
ViewPager vpContent;
@InjectView(R.id.tl_tab)
TabLayout tlTab;
@InjectView(R.id.toolBar)
Toolbar toolBar;
private List tabIndicators;
private List tabImages;
private List tabFragments;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
initToolBar();
initContent();
initTab();
}
private void initToolBar() {
toolBar.setTitle("TabLayout");
toolBar.setTitleTextColor(getResources().getColor(R.color.colorToolBarTitle));
}
private void initTab() {
tlTab.setTabMode(TabLayout.MODE_FIXED);
tlTab.setSelectedTabIndicatorHeight(0);
ViewCompat.setElevation(tlTab, 10);
tlTab.setupWithViewPager(vpContent);
for (int i = 0; i < tabIndicators.size(); i++) {
TabLayout.Tab itemTab = tlTab.getTabAt(i);
if (itemTab != null) {
itemTab.setCustomView(R.layout.item_tab_layout_custom);
TextView itemTv = (TextView) itemTab.getCustomView().findViewById(R.id.itemTextView);
ImageView itemIv = (ImageView) itemTab.getCustomView().findViewById(R.id.itemImageView);
itemTv.setText(tabIndicators.get(i));
itemIv.setImageResource(tabImages.get(i));
}
}
tlTab.getTabAt(0).getCustomView().setSelected(true);
}
private void initContent() {
tabIndicators = new ArrayList<>();
tabIndicators.add("消息");
tabIndicators.add("任务");
tabIndicators.add("团队");
tabIndicators.add("部门");
tabImages = new ArrayList<>();
tabImages.add(R.drawable.main_tabs_message_normal);
tabImages.add(R.drawable.main_tabs_task_normal);
tabImages.add(R.drawable.main_tabs_team_normal);
tabImages.add(R.drawable.main_tabs_depart_normal);
tabFragments = new ArrayList<>();
for (String s : tabIndicators) {
tabFragments.add(TabContentFragment.newInstance(s));
}
ContentPagerAdapter contentAdapter = new ContentPagerAdapter(getSupportFragmentManager());
vpContent.setAdapter(contentAdapter);
}
private class ContentPagerAdapter extends FragmentPagerAdapter {
public ContentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return tabFragments.get(position);
}
@Override
public int getCount() {
return tabIndicators.size();
}
@Override
public CharSequence getPageTitle(int position) {
return tabIndicators.get(position);
}
}
}
public class TabContentFragment extends Fragment {
private String text;
public TabContentFragment(String text) {
this.text = text;
}
public static Fragment newInstance(String s) {
return new TabContentFragment(s);
}
@Override
public void onAttach(Context context) {
Log.e("TYH", text + "onAttach");
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.e("TYH", text + "onCreate");
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.e("TYH", text + "onCreateView");
TextView textView = new TextView(getContext());
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
textView.setLayoutParams(layoutParams);
textView.setGravity(Gravity.CENTER);
textView.setText(text);
return textView;
}
@Override
public void onStart() {
Log.e("TYH", text + "onStart");
super.onStart();
}
@Override
public void onResume() {
Log.e("TYH", text + "onResume");
super.onResume();
}
@Override
public void onPause() {
Log.e("TYH", text + "onPause");
super.onPause();
}
@Override
public void onStop() {
Log.e("TYH", text + "onStop");
super.onStop();
}
@Override
public void onDestroyView() {
Log.e("TYH", text + "onDestroyView");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.e("TYH", text + "onDestroy");
super.onDestroy();
}
@Override
public void onDetach() {
Log.e("TYH", text + "onDetach");
super.onDetach();
}
}
05-09 14:47:39.593 31509-31509/tyh.com.tablayout E/TYH: 团队onAttach
05-09 14:47:39.593 31509-31509/tyh.com.tablayout E/TYH: 团队onCreate
05-09 14:47:39.593 31509-31509/tyh.com.tablayout E/TYH: 团队onCreateView
05-09 14:47:39.603 31509-31509/tyh.com.tablayout E/TYH: 团队onStart
05-09 14:47:39.603 31509-31509/tyh.com.tablayout E/TYH: 团队onResume
大家可能有疑问,奇怪!怎么没走任务Fragment的任何生命周期?
答:这是因为进入MainActivity时Fragment 声明周期发生了如下变化:
05-09 14:48:14.170 31509-31509/tyh.com.tablayout E/TYH: 消息onAttach
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 消息onCreate
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 消息onCreateView
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 消息onStart
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 消息onResume
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 任务onAttach
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 任务onCreate
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 任务onCreateView
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 任务onStart
05-09 14:48:14.180 31509-31509/tyh.com.tablayout E/TYH: 任务onResume
也就是说,进入界面之后。
ViewPager默认会给我们初始化好前面2个Fragment的内容。
当我们切换到第二个Fragment的时候,初始化好第三个Fragment。
05-09 14:55:26.932 31509-31509/tyh.com.tablayout E/TYH: 消息onPause
05-09 14:55:26.932 31509-31509/tyh.com.tablayout E/TYH: 消息onStop
05-09 14:55:26.932 31509-31509/tyh.com.tablayout E/TYH: 消息onDestroyView
05-09 14:55:26.932 31509-31509/tyh.com.tablayout E/TYH: 部门onAttach
05-09 14:55:26.932 31509-31509/tyh.com.tablayout E/TYH: 部门onCreate
05-09 14:55:26.942 31509-31509/tyh.com.tablayout E/TYH: 部门onCreateView
05-09 14:55:26.942 31509-31509/tyh.com.tablayout E/TYH: 部门onStart
05-09 14:55:26.942 31509-31509/tyh.com.tablayout E/TYH: 部门onResume
由生命周期可见,任务到团队的切换过程中,将消息Fragment给干掉了,把部门给初始化完毕了。
05-09 14:57:18.371 31509-31509/tyh.com.tablayout E/TYH: 任务onPause
05-09 14:57:18.371 31509-31509/tyh.com.tablayout E/TYH: 任务onStop
05-09 14:57:18.371 31509-31509/tyh.com.tablayout E/TYH: 任务onDestroyView
05-09 15:00:50.918 31509-31509/tyh.com.tablayout E/TYH: 任务onCreateView
05-09 15:00:50.918 31509-31509/tyh.com.tablayout E/TYH: 任务onStart
05-09 15:00:50.918 31509-31509/tyh.com.tablayout E/TYH: 任务onResume
05-09 15:01:15.134 31509-31509/tyh.com.tablayout E/TYH: 消息onCreateView
05-09 15:01:15.144 31509-31509/tyh.com.tablayout E/TYH: 部门onPause
05-09 15:01:15.144 31509-31509/tyh.com.tablayout E/TYH: 部门onStop
05-09 15:01:15.144 31509-31509/tyh.com.tablayout E/TYH: 部门onDestroyView
05-09 15:01:15.144 31509-31509/tyh.com.tablayout E/TYH: 消息onStart
05-09 15:01:15.144 31509-31509/tyh.com.tablayout E/TYH: 消息onResume
05-09 15:02:07.890 31509-31509/tyh.com.tablayout E/TYH: 团队onPause
05-09 15:02:07.890 31509-31509/tyh.com.tablayout E/TYH: 团队onStop
05-09 15:02:07.890 31509-31509/tyh.com.tablayout E/TYH: 团队onDestroyView
滑动时几个Fragment生命周期与切换相同
接下来贴出间隔3个Fragment之间切换生命周期变化
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 团队onAttach
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 团队onCreate
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 团队onCreateView
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 团队onStart
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 团队onResume
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 部门onAttach
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 部门onCreate
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 部门onCreateView
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 部门onStart
05-09 15:04:41.284 31509-31509/tyh.com.tablayout E/TYH: 部门onResume
05-09 15:04:41.614 31509-31509/tyh.com.tablayout E/TYH: 消息onPause
05-09 15:04:41.614 31509-31509/tyh.com.tablayout E/TYH: 消息onStop
05-09 15:04:41.614 31509-31509/tyh.com.tablayout E/TYH: 消息onDestroyView
可见首先是团队的初始化,接下来是部门的初始化,再者是消息的销毁
接下来贴出间隔4个Fragment之间切换生命周期变化
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 部门onAttach
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 部门onCreate
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 部门onCreateView
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 部门onStart
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 部门onResume
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 团队onAttach
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 团队onCreate
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 团队onCreateView
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 团队onStart
05-09 15:07:02.684 31509-31509/tyh.com.tablayout E/TYH: 团队onResume
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 任务onPause
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 任务onStop
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 任务onDestroyView
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 消息onPause
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 消息onStop
05-09 15:07:03.135 31509-31509/tyh.com.tablayout E/TYH: 消息onDestroyView
首先是部门的初始化,接下来是团队的初始化,再者是任务和消息的销毁
ViewPager从其内部Fragment的生命周期的变化大家可以看出来一个规律:
1. 当左右可以滑动时,始终保持左右的Fragment初始化完毕,可以说是一个预加载效果
2. 当不处于当前展示的位置左右时,执行onPause、onStop、onDestroyView方法