Acitivity和Fragment的生命周期研究
前言
先分别研究界面跳转、对话框的弹出、返回键、home键、锁屏与解锁对Activity和Fragment各自的生命周期影响。之后研究在activity中使用fragment时activity生命周期变化对fragment生命周期的影响。最后研究使用android的Viewpager在设置缓存和不设置缓存的情况下对两者生命周期的影响。
一、 Activity的生命周期
Activity生命周期图
<1> 四种状态
1.活动(Active/Running)状态
当Activity运行在屏幕前台(处于当前任务活动栈的最上面),此时它获取了焦点能响应用户的操作,属于运行状态,同一个时刻只会有一个Activity 处于活动(Active)或运行(Running)状态
2.暂停(Paused)状态
当Activity失去焦点但仍对用户可见(如在它之上有另一个透明的Activity或Toast、AlertDialog等弹出窗口时)它处于暂停状态。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但是当系统内存极小时可以被系统杀掉
3.停止(Stopped)状态
完全被另一个Activity遮挡时处于停止状态,它仍然保留着所有的状态和成员信息。只是对用户不可见,当其他地方需要内存时它往往被系统杀掉
4.非活动(Dead)状态
Activity 尚未被启动、已经被手动终止,或已经被系统回收时处于非活动的状态,要手动终止Activity,可以在程序中调用"finish"方法。
如果是(按根据内存不足时的回收规则)被系统回收,可能是因为内存不足了
内存不足时,Dalvik 虚拟机会根据其内存回收规则来回收内存:
(1)先回收与其他Activity 或Service/Intent Receiver 无关的进程(即优先回收独立的Activity)因此建议,我们的一些(耗时)后台操作,最好是作成Service的形式
(2).不可见(处于Stopped状态的)Activity
(3)Service进程(除非真的没有内存可用时会被销毁)
(4)非活动的可见的(Paused状态的)Activity
(5)当前正在运行(Active/Running状态的)Activity
<2> 7个重要方法
当Activity从一种状态进入另一状态时系统会自动调用下面相应的方法来通知用户这种变化,当Activity第一次被实例化的时候系统会调用,整个生命周期只调用1次,这个方法常用于初始化设置:
1、为Activity设置所要使用的布局文件
2、为按钮绑定监听器等静态的设置操作
onCreate(BundlesavedInstanceState);
当Activity可见未获得用户焦点不能交互时系统会调用
onStart();
当Activity已经停止然后重新被启动时系统会调用
onRestart();
当Activity可见且获得用户焦点能交互时系统会调用
onResume();
当系统启动另外一个新的Activity时,在新Activity启动之前被系统调用保存现有的Activity中的持久数据、停止动画等,这个实现方法必须非常快。当系统而不是用户自己出于回收内存时,关闭了activity 之后。用户会期望当他再次回到这个activity 的时候,它仍保持着上次离开时的样子。此时用到了onSaveInstanceState(),方法onSaveInstanceState()用来保存Activity被杀之前的状态,在onPause()之前被触发,当系统为了节省内存销毁了Activity(用户本不想销毁)时就需要重写这个方法了,当此Activity再次被实例化时会通过onCreate(Bundle savedInstanceState)将已经保存的临时状态数据传入因为onSaveInstanceState()方法不总是被调用,触发条件为(按下HOME键,按下电源按键关闭屏幕,横竖屏切换情况下),你应该仅重写onSaveInstanceState()来记录activity的临时状态,而不是持久的数据。应该使用onPause()来存储持久数据。
onPause();
当Activity被新的Activity完全覆盖不可见时被系统调用
onStop();
当Activity(用户调用finish()或系统由于内存不足)被系统销毁杀掉时系统调用,(整个生命周期只调用1次)用来释放onCreate()方法中创建的资源,如结束线程等
onDestroy();
<3> 3个嵌套循环
1.Activity完整的生命周期:从第一次调用onCreate()开始直到调用onDestroy()结束
2.Activity的可视生命周期:从调用onStart()到相应的调用onStop()
在这两个方法之间,可以保持显示Activity所需要的资源。如在onStart()中注册一个广播接收者监听影响你的UI的改变,在onStop() 中注销。
3.Activity的前台生命周期:从调用onResume()到相应的调用onPause()。
<4> demo:界面跳转、对话框、返回键、Home键、横竖屏切换对activity生命周期的影响
这个工程有两个activity,第一个activity中有两个按钮,一个按钮是弹出对话框,一个按钮时条换到第二个activity,通过log来观察两个activity的生命周期的变化
MainActivity.java
public classMainActivity extends Activityimplements OnClickListener{
privateButtonjump,showdialog;
@Override
protected void onCreate(BundlesavedInstanceState) {
Log.v("tag", "activity 1 onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jump=(Button)findViewById(R.id.jump);
showdialog=(Button)findViewById(R.id.showdialog);
jump.setOnClickListener(this);
showdialog.setOnClickListener(this);
}
@Override
protected void onDestroy() {
Log.v("tag", "activity 1 onDestroy");
super.onDestroy();
}
@Override
protected void onPause() {
Log.v("tag", "activity 1 onPause");
super.onPause();
}
@Override
protected void onRestart() {
Log.v("tag", "activity 1 onRestart");
super.onRestart();
}
@Override
protected void onResume() {
Log.v("tag", "activity 1 onResume");
super.onResume();
}
@Override
protected void onStart() {
Log.v("tag", "activity 1 onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.v("tag", "activity 1 onStop");
super.onStop();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.jump:
Intentintent =new Intent(MainActivity.this , TestActivity1.class);
startActivity(intent);
break;
case R.id.showdialog:
newAlertDialog.Builder(MainActivity.this).setTitle("弹出对话框").setPositiveButton("确定",null).show();
break;
}
}
}
Test1Activity.java
public classTestActivity1 extends Activity {
@Override
protected void onCreate(BundlesavedInstanceState) {
Log.v("tag", "activity 2 onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_activity1);
}
@Override
protected void onDestroy() {
Log.v("tag", "activity 2 onDestroy");
super.onDestroy();
}
@Override
protected void onPause() {
Log.v("tag", "activity 2 onPause");
super.onPause();
}
@Override
protected void onRestart() {
Log.v("tag", "activity 2 onRestart");
super.onRestart();
}
@Override
protected void onResume() {
Log.v("tag", "activity 2 onResume");
super.onResume();
}
@Override
protected void onStart() {
Log.v("tag", "activity 2 onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.v("tag", "activity 2 onStop");
super.onStop();
}
}
程序刚运行时:
activiy 1 oncreate -> activity 1 onstart -> activity onresume
点击弹出对话框按钮,发觉log没有任何变化
点击跳转按钮跳转到第二个activity
activity 1 onpause -> activity 2oncreate -> activity 2 onstart -> activity 2 onresume -> activity 1 onstop
按下返回键返回第一个activity
activity 2 onpause -> activity 1onrestart -> activity 1 onstart -> activity 1 onresume -> activity 2onstop -> activity 2 ondestroy
注意:当点击返回的时候,这里调用的不是FirstActivity的onCreate()方法而是onRestart()方法,因为在之前FirstActivity已经被创建过了并且没有销毁,只要当FirstActivity销毁了再调用FirstActivity的时候才会调用onCreate()方法。
按下home键
activity 1 onpause -> activity 1 onstop
由此可见,Back键和Home键主要区别在于是否会执行onDestroy。
上面在描述onStop()方法的时候有说到,只有当Activity处于不可见状态,完全被新的Activity覆盖时才会调用之前Activity的此方法。如果只是在现有的Activity上弹出一个对话框,没有完全覆盖现有的Activity,那么是不会调用此方法的。
对程序进行修改,将第二个Activity修改成对话框形式进行显示,来看一下Activity的生命周期。
对话框形式的Activity与普通Activity没太大区别,只需要将AndroidManifest.xml文件中的对应的Activity标签增加以下这么一个属性即可。
android:theme="@android:style/Theme.Dialog"
运行程序,然后点击按钮跳转到第二个activity,此时第二个activity是以对话框的形式展示
可见,此时就调用了activity1的onpause方法
根据输出内容可观察到,与刚刚相比,该应用程序没有运行Activity1的onStop()方法。
所以,只有现有的Activity被新的Activity完全覆盖的时候,才会调用之前Activity的onStop()方法。
横竖屏切换
运行activity
按下小键盘7切换为竖屏,输出了
再按下小键盘9切换回横屏,输出了
不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
锁屏/解锁
锁屏时会调用onpause方法,而在激活屏幕准备解锁前会调用onresume
二、 Fragment的生命周期
Fragment生命周期图
Fragment可以生存在三种状态:
Resumed:
Fragment在一个运行中的activity中并且可见。
Paused:
另一个activity处于最顶层,但是fragment所在的activity并没有被完全覆盖(顶层的activity是半透明的或不占据整个屏幕)。
Stoped:
Fragment不可见。可能是它所在的activity处于stoped状态或是fragment被删除并添加到后退栈中了。此状态的fragment仍然存在于内存中。
同样类似于activity,你可以把fragment的状态保存在一个Bundle中,在activity被recreated时就需用到这个东西。你可以在onSaveInstanceState()方法中保存状态并在onCreate()或onCreateView()或onActivityCreated()中恢复,关于更多的保存状态的信息,请参考Activitys章节。
Fragment与Activity的生命周期中最大的不同就是存储到后退栈中的过程。Activity是在停止时自动被系统压入停止栈,并且这个栈是被系统管理的;而fragment是被压入activity所管理的一个后退栈,并且只有你在删除fragment后并明确调用addToBackStack()方法时才被压入。
Demo:由一个activity添加一个fragment,第一个fragment为一个列表,点击列表项进入第二个fragment
MainActivity.java
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
public classMainActivity extends FragmentActivityimplements HeadlinesFragment.OnHeadlineSelectedListener {
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
if(findViewById(R.id.fragment_container)!=null){
if(savedInstanceState !=null) {
return;
}
HeadlinesFragmentfisrtFragment = newHeadlinesFragment();
fisrtFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,fisrtFragment).commit();
}
}
@Override
public void onArticleSelected(int position) {
ArticleFragmentarticleFrag = (ArticleFragment)getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if(articleFrag !=null) {
articleFrag.updateArticleView(position);
} else {
ArticleFragment newFragment =new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransactiontransaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container,newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
列表fragment: HeadlinesFragment.java
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public classHeadlinesFragmentextendsListFragment {
OnHeadlineSelectedListenermCallback;
public interfaceOnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("tag", "HeadlinesFragment onCreate()");
int layout = Build.VERSION.SDK_INT >=Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1
:android.R.layout.simple_list_item_1;
setListAdapter(newArrayAdapter
Ipsum.Headlines));
}
@Override
public void onStart() {
super.onStart();
Log.i("tag", "HeadlinesFragment onStart()");
if(getFragmentManager().findFragmentById(R.id.article_fragment) !=null) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
}
@Override
public void onPause() {
super.onPause();
Log.i("tag", "HeadlinesFragment onPause()");
}
@Override
public void onResume() {
super.onResume();
Log.i("tag", "HeadlinesFragment onResume()");
}
@Override
public void onStop() {
super.onStop();
Log.i("tag", "HeadlinesFragment onStop()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("tag", "HeadlinesFragment onDestroy()");
}
@Override
public void onDetach() {
super.onDetach();
Log.i("tag", "HeadlinesFragment onDetach()");
}
@Override
public voidonActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("tag", "HeadlinesFragment onActivityCreated()");
}
@Override
public void onAttach(Activityactivity) {
super.onAttach(activity);
Log.i("tag", "HeadlinesFragment onAttach()");
try {
mCallback =(OnHeadlineSelectedListener) activity;
}catch(ClassCastException e) {
throw newClassCastException(activity.toString()
+" must implementOnHeadlineSelectedListener");
}
}
@Override
public ViewonCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState) {
Log.i("tag", "HeadlinesFragment onCreateView()");
return super.onCreateView(inflater,container, savedInstanceState);
}
@Override
public voidonListItemClick(ListView l, View v, int position,long id) {
mCallback.onArticleSelected(position);
getListView().setItemChecked(position,true);
}
}
详情fragment ArticleFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public classArticleFragmentextendsFragment {
final static String ARG_POSITION ="position";
int mCurrentPosition = -1;
@Override
public ViewonCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState) {
if (savedInstanceState !=null) {
mCurrentPosition =savedInstanceState.getInt(ARG_POSITION);
}
Log.i("tag", "ArticleFragmentonCreateView()");
returninflater.inflate(R.layout.article_view, container,false);
}
@Override
public void onStart() {
super.onStart();
Log.i("tag","ArticleFragment onStart()");
Bundleargs = getArguments();
if(args !=null) {
updateArticleView(args.getInt(ARG_POSITION));
}else if(mCurrentPosition!= -1){
updateArticleView(mCurrentPosition);
}
}
@Override
public voidonActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("tag","ArticleFragment onActivityCreated()");
}
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("tag", "ArticleFragment onCreate()");
}
@Override
public void onStop() {
super.onStop();
Log.i("tag", "ArticleFragment onStop()");
}
@Override
public void onResume() {
super.onResume();
Log.i("tag", "ArticleFragment onResume()");
}
@Override
public void onPause() {
super.onPause();
Log.i("tag", "ArticleFragment onPause()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("tag", "ArticleFragment onDestroy()");
}
@Override
public void onDetach() {
super.onDetach();
Log.i("tag", "ArticleFragment onDetach()");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.i("tag", "ArticleFragment onDestroyView()");
}
public void updateArticleView(int position) {
TextViewarticle = (TextView) getActivity().findViewById(R.id.article);
article.setText(Ipsum.Articles[position]);
mCurrentPosition = position;
}
@Override
public voidonSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(ARG_POSITION,mCurrentPosition);
}
}
存储字符串的类 Ipsum.java
public classIpsum {
static String[]Headlines = {
"Article One",
"Article Two"
};
staticString[]Articles= {
"Article One\n\nExcepteur pour-over occaecat squid biodiesel umamigastropub, nulla laborum salvia dreamcatcher fanny pack. Ullamco culpa retroea, trust fund excepteur eiusmod direct trade banksy nisi lo-fi cray messengerbag. Nesciunt esse carles selvage put a bird on it gluten-free, wes anderson uttrust fund twee occupy viral. Laboris small batch scenester pork belly,leggings ut farm-to-table aliquip yr nostrud iphone viral next level. Craftbeer dreamcatcher pinterest truffaut ethnic, authentic brunch. Essesingle-origin coffee banksy do next level tempor. Velit synth dreamcatcher,magna shoreditch in american apparel messenger bag narwhal PBR ennuifarm-to-table.",
"Article Two\n\nVinyl williamsburg non velit, master cleanse fourloko banh mi. Enim kogi keytar trust fund pop-up portland gentrify. Non eatypewriter dolore deserunt Austin. Ad magna ethical kogi mixtape next level.Aliqua pork belly thundercats, ut pop-up tattooed dreamcatcher kogi accusamusphoto booth irony portland. Semiotics brunch ut locavore irure, enim etsylaborum stumptown carles gentrify post-ironic cray. Butcher 3 wolf moon blogsynth, vegan carles odd future."
};
}
article_view.xml
xmlversion="1.0"encoding="utf-8"?>
<TextViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/article"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textSize="18sp"/>
news_articles.xml
xmlversion="1.0"encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
activity_main.xml
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="@dimen/padding_medium"
android:text="@string/hello_world"
tools:context=".MainActivity"/>
RelativeLayout>
进入主界面后,输出
点击列表项进入别的fragment,输出
点击返回键返回第一个fragment,输出
锁屏,输出
点亮屏幕,输出
小键盘7,转换为横屏,输出
小键盘9,转换回竖屏,输出
三、Activity中使用Fragment时两者生命周期的关系
与Activity生命周期的对比图
从图中可以看出,activity和相应的fragment在生命周期上其实是对应的
Activity直接影响它所包含的fragment的生命周期,所以对activity的某个生命周期方法的调用也会产生对fragment相同方法的调用。例如:当activity的onPause()方法被调用时,它所包含的所有的fragment们的onPause()方法都会被调用。
Fragment比Activity还要多出几个生命周期回调方法,这些额外的方法是为了与Activity的交互而设立,如下:
onAttach():当fragment被加入到activity时调用(在这个方法中可以获得所在的activity)。
onCreateView():当activity要得到fragment的layout时,调用此方法,fragment在其中创建自己的layout(界面)。
onActivityCreated()
当activity的onCreated()方法返回后调用此方法。
onDestroyView()
当fragment的layout被销毁时被调用。
onDetach()
当fragment被从activity中删掉时被调用。
一旦activity进入resumed状态(也就是running状态),你就可以自由地添加和删除fragment了。因此,只有当activity在resumed状态时,fragment的生命周期才能独立的运转,其它时候是依赖于activity的生命周期变化的。
对上述工程稍作修改,将第一个工程中的窗口activity加到上述工程中,将activity的生命周期也log出来,然后看两者的关系
程序运行后,先activity的oncreate和onstart,然后进入fragment的onattach一直到onstart,然后到activity的onresume,再之后就是fragment的onresume,输出
点击列表项,进入第二个fragment,进入第二个fragment跟activity没什么关系,输出
点击返回键返回列表fragment,输出
点击按钮,将第二个activity以对话框的方式显示,在activityonpause之后fragment也进入了onpause方法,输出
点击返回,返回第一个activity,显示activityonresume,之后fragment跟着onresume,输出
锁屏,输出
解锁,输出
点击home键
返回程序
按下返回键,输出
综上,fragment和当前的activity生命周期总是对应的,fragment的生命周期依赖于当前的activity
四、Viewpager在是否设置缓存的情况下对两者生命周期的影响。
在viewpager中可以通过setOffscreenPageLimit()方法设置缓存页面个数,默认为1
工程为滑动的fragment
第一种情况:没有缓存 setOffscreenPageLimit(0)
MainActivity.java
importjava.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.PagerTitleStrip;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.ViewGroup;
public classMainActivity extends FragmentActivity {
private ViewPagerm_vp;
private fragment1mfragment1;
private fragment2mfragment2;
private fragment3mfragment3;
//页面列表
privateArrayList
//标题列表
ArrayList
//通过pagerTabStrip可以设置标题的属性
private PagerTabStrippagerTabStrip;
private PagerTitleStrippagerTitleStrip;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("tag", "activity onCreate");
setContentView(R.layout.activity_main);
m_vp =(ViewPager)findViewById(R.id.viewpager);
m_vp.setOffscreenPageLimit(0);
pagerTabStrip=(PagerTabStrip)findViewById(R.id.pagertab);
//设置下划线的颜色
pagerTabStrip.setTabIndicatorColor(getResources().getColor(android.R.color.holo_green_dark));
//设置背景的颜色
pagerTabStrip.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_dark));
// pagerTitleStrip=(PagerTitleStrip)findViewById(R.id.pagertab);
// //设置背景的颜色
// pagerTitleStrip.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_dark));
mfragment1 = new fragment1();
mfragment2 = new fragment2();
mfragment3 = new fragment3();
fragmentList = newArrayList
fragmentList.add(mfragment1);
fragmentList.add(mfragment2);
fragmentList.add(mfragment3);
titleList.add("第一页 ");
titleList.add("第二页");
titleList.add("第三页 ");
m_vp.setAdapter(newMyViewPagerAdapter(getSupportFragmentManager()));
}
@Override
protected void onDestroy() {
Log.v("tag", "activity onDestroy");
super.onDestroy();
}
@Override
protected void onPause() {
Log.v("tag", "activity onPause");
super.onPause();
}
@Override
protected void onResume() {
Log.v("tag", "activity onResume");
super.onResume();
}
@Override
protected void onStart() {
Log.v("tag", "activity onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.v("tag", "activity onStop");
super.onStop();
}
public class MyViewPagerAdapter extends FragmentPagerAdapter{
publicMyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
returnfragmentList.get(arg0);
}
@Override
public int getCount() {
returnfragmentList.size();
}
@Override
public CharSequencegetPageTitle(intposition) {
// TODO Auto-generated method stub
returntitleList.get(position);
}
}
}
fragment1.java 、fragment2.java 、 fragment3.java都是一样的
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public classfragment2 extendsFragment{
private ViewmMainView;
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("tag", "fragment2-->onCreate()");
LayoutInflaterinflater = getActivity().getLayoutInflater();
mMainView =inflater.inflate(R.layout.fragment2, (ViewGroup)getActivity().findViewById(R.id.viewpager),false);
}
@Override
public ViewonCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState) {
Log.v("tag", "fragment2-->onCreateView()");
ViewGroupp = (ViewGroup) mMainView.getParent();
if (p !=null) {
p.removeAllViewsInLayout();
Log.v("tag","fragment2-->移除已存在的View");
}
returnmMainView;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v("tag", "fragment2-->onDestroy()");
}
@Override
public void onPause() {
super.onPause();
Log.v("tag", "fragment2-->onPause()");
}
@Override
public void onResume() {
super.onResume();
Log.v("tag", "fragment2-->onResume()");
}
@Override
public void onStart() {
super.onStart();
Log.v("tag", "fragment2-->onStart()");
}
@Override
public void onStop() {
super.onStop();
Log.v("tag", "fragment2-->onStop()");
}
}
activity_main.xml
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pagertab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
android.support.v4.view.ViewPager>
RelativeLayout>
fragment1.xml 、fragment2.xml 、 fragment3.xml都是一样的
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#00FF00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="第二个fragment"
/>
LinearLayout>
运行程序,输出:
划向第二个fragment,输出
划向第三个fragment,输出
再划回第二个fragment,输出
划回第一个fragment,输出
点击返回键退出
再将setOffscreenPageLimit设置为2,进行同样的动作
进入程序:输出
之后发现,划向任何一个fragment都没有输出
按返回键退出,输出