android activity与fragment的生命周期详细研究
Acitivity和Fragment的生命周期研究
前言
首先系统性地探讨界面对象及其交互操作对于Android组件生命周期的影响机制。具体而言,本研究将分别考察界面切换过程、消息弹出机制、返回操作(包括主功能键操作)以及屏幕锁定与解锁操作对Activity与Fragment各自生命周期特征的作用。随后深入分析当采用Fragment作为Activity子组件时,活动组件在其自身生命周期变化过程中对其自身所包含的Fragment组件产生何种影响。最终聚焦于分析基于Android系统的ViewPager组件在启用缓存模式与非启用缓存模式下对其所支持的各项功能组件及其整体应用架构运行周期性特征的具体表现差异。
一、 Activity的生命周期
Activity生命周期图
<1> 四种状态
1.活动(Active/Running)状态
当某个Activity处于屏幕前台(位于当前任务活动栈顶端),它拥有焦点权并能够处理用户的请求。同一时间段内只有一个Activity会处于活跃(Active)或运行(Running)的状态。
2.暂停(Paused)状态
当Focus被取消但仍使用户可见(例如,在其上方出现另一个透明的Activity或Toast、AlertDialog等弹出窗口的时候),该Application处于暂停状态。暂停的Application依然保持着所有状态与成员信息,并持续与窗口管理器保持连接,在系统内存极度低的时候可能会被系统kill掉。
3.停止(Stopped)状态
当一个Activity完全被另一个Activity覆盖并处于停止状态时,它仍然保持着全部的状态信息和成员数据.然而,在用户界面中它是不可见的,而当系统在其他地方需要内存资源时,这个Process通常会被操作系统终止.
4.非活动(Dead)状态
当Activity处于非活动状态时(包括未启动、被强行停止或被系统回收),可以通过在代码中调用该方法来实现相应的操作
当Activity处于非活动状态时(包括未启动、被强行停止或被系统回收),可以通过在代码中调用该方法来实现相应的操作
当系统按照内存不足时的回收规则进行处理时,可能是由于内存不足导致的。
内存不足时,Dalvik 虚拟机会根据其内存回收规则来回收内存:
优先清除那些不涉及其他Activity或其他Service/Intent Receiver的部分(即专注于处理独立Activity的任务)。鉴于此建议,我们应当将一些长时间运行的任务转换为Service形式。
(2).不可见(处于Stopped状态的)Activity
(3)Service进程(除非真的没有内存可用时会被销毁)
(4)非活动的可见的(Paused状态的)Activity
(5)当前正在运行(Active/Running状态的)Activity
<2> 7个重要方法
每当Activity从一种状态进入另一种状态时,在此期间系统将触发相应的操作流程来告知用户这种变化。在首次实例化时系统将执行该操作流程一次,在整个生命周期中仅执行一次。该流程主要应用于设备初始化配置阶段:
1、为Activity设置所要使用的布局文件
2、为按钮绑定监听器等静态的设置操作
onCreate(BundlesavedInstanceState);
当Activity可见未获得用户焦点不能交互时系统会调用
onStart();
当Activity已经停止然后重新被启动时系统会调用
onRestart();
当Activity可见且获得用户焦点能交互时系统会调用
onResume();
每当系统启动一个新的Activity前,在新Activity启动之前被系统调用时
onPause();
当Activity被新的Activity完全覆盖不可见时被系统调用
onStop();
当Activity在用户触发Finish事件或因内存不足而被强行销毁时会触发此操作,并且该操作仅会在完整生命周期运行一次。该操作用于释放onCreate方法初始化阶段所创建的资源,并包括终止所有相关线程等处理工作。
onDestroy();
<3> 3个嵌套循环
Activity的完整生命周期流程涵盖从onCreate()方法启动到onDestroy()方法终止的整个过程
2.Activity的可视生命周期:从调用onStart()到相应的调用onStop()
可以在两个方法之间维持显示Activity所需的资源。例如,在onStart()阶段注册一个广播接收器来监听会影响UI的变化,在onStop()阶段则进行注销操作。
3.Activity的前台生命周期:从调用onResume()到相应的调用onPause()。
<4> demo:导航切换、消息框、退出键、主屏切换及屏幕旋转操作对activity生命周期的作用
该工程包含两个Activity,在第一个Activity中设有两个Button其中一个Button用于弹出对话框而另一个Button负责将流程切换至第二个Activity借助日志文件追踪这两个Activity在整个运行过程中的生命周期变化情况
MainActivity.java
此活动管理主类将作为公有类型,并直接继承自基础框架中的Activity,并实现所需的Listener接口以处理相应的事件监听功能。
private Buttonjump,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 :
创建一个新的 AlertDialog Builder,并将其作为父级应用使用到 MainActivity 的 this 实例上。
设置为弹出对话框标题 "弹出对话框"。
将 "确定" 弹出按钮设置为 null(即不带图片)。
显示这个 AlertDialog 对话框。
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 one paused at this point, followed by activity two creating a new task, which then began the process of starting. Activity two resumed progress after that, and finally, activity one terminated the pause.
按下返回键返回第一个activity
activity two paused at the current stage -> the activity one is about to restart -> the activity one has just started -> the activity one is in the resumption stage -> the activity two is now stopped -> the activity two has just been destroyed
请注意:当用户点击返回时,系统会触发的是onRestart()事件而非启动方法(即onCreate())。由于在首次操作后该FirstActivity已存在且未被销毁,在该对象被销毁并重新创建时才会有启动方法被触发执行。
按下home键
activity 1 onpause -> activity 1 onstop
由此可见,Back键和Home键主要区别在于是否会执行onDestroy。
在描述onStop()方法时指出:该方法仅在现有Activity被新的Activity完全覆盖时才被调用。若只是在现有Activity上展示一个对话框而未完全覆盖,则不会触发该方法。通过将第二个Activity调整为对话框显示形式以观察其生命周期变化。值得注意的是:虽然二者功能接近但并非无差别。只需在AndroidManifest.xml中增加对应属性即可实现对话框显示:android:theme="@android:style/Theme.Dialog"
启动程序后,请单击按钮以引导至第二个activity;该activity采用对话框界面呈现
可见,此时就调用了activity1的onpause方法
通过输出结果可以看出,在比较之后发现该应用程序不执行Activity1的onStop()方法。原因在于只有当现有Activity被新的Activity完全覆盖时才触发调用。
横竖屏切换
运行activity
按下小键盘7切换为竖屏,输出了
再按下小键盘9切换回横屏,输出了
当Activity未配置android:configChanges属性时,在进行切屏操作时会触发各个生命周期的一次性事件;具体而言,在横向滑动的情况下只会触发一次生命周期,在纵向滑动的情况下则会触发两次事件
锁屏/解锁
锁屏时会调用onpause方法,而在激活屏幕准备解锁前会调用onresume
二、 Fragment的生命周期
Fragment生命周期图
Fragment可以生存在三种状态:
Resumed:
Fragment在一个运行中的activity中并且可见。
Paused:
该another activity is positioned as the top layer, but the activity where the fragment is located is not fully covered (and may be semi-transparent or does not occupy the entire viewport).
Stoped:
fragment无法显示。可能的原因在于该activity的状态为停止(stopped),或者在发生异常时该fragment已被移除并重新添加到回滚栈中。此时该state下的fragment依然保留在内存里。
类似地,在Android系统中
Fragment与Activity的生命周期中最大的不同在于它们如何处理回滚过程。每当Application进行退出操作时(即当应用完成工作流程并准备退出),会将当前的应用实例自动推入SystemStack进行处理;此外, 该Stack由系统直接管理。而Fragment则仅在您主动执行Delete操作并调用addToBackStack()之后才会被推入到对应的回滚队列中。
本例中使用了一个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 ;
AndroidManifestVersion 1.0 public class MainActivity superclass of FragmentActivity implements HeadlinesFragment.OnTopSelectedListener {
@Override
public voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
if(findViewById(R.id.fragment_container)!=null){
if(savedInstanceState !=null) {
return ;
}
HeadlinesFragmentfisrtFragment = new HeadlinesFragment();
fisrtFragment.setArguments(getIntent().getExtras());
$this().beginTransaction().设置R.id._fragment_container_属性的值为fisrtFragment.保存事务;
}
}
@Override
public void onArticleSelected(int position) {
int articleFragments = (int) get_xiaomi().getArticleFragmentById(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);
$transaction = current.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 classHeadlinesFragmentextends ListFragment {
OnHeadlineSelectedListenermCallback;
public interfaceOnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("tag", "HeadlinesFragment onCreate()");
首先检查Build\ SDK\ _VERSION.\ _SDK\_INT中的整数属性是否大于等于Build\ VERSION\ _CODES.\ _HONEYCOMB中的整数属性;如果是,则将layout设置为android.\ R.\ layout.\ _simple\_list\_item\_activated\_1;否则不进行设置或其他操作。
:android.R.layout.simple_list_item_1 ;
setListAdapter(new ArrayAdapter
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 inflater, where the style is set to intensity 1 and the container is specified.
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 classArticleFragmentextends Fragment {
final static String ARG_POSITION ="position";
int mCurrentPosition = -1;
@Override
在Android开发中,请注意自定义视图工厂方法inflater和其容器组件container的相关实现
BundlesavedInstanceState) {
if (savedInstanceState !=null) {
mCurrentPosition =savedInstanceState.getInt(ARG_POSITION);
}
Log.i("tag", "ArticleFragmentonCreateView()");
return inflater.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"
};
static String[]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
<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
<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" />
进入主界面后,输出
点击列表项进入别的fragment,输出
点击返回键返回第一个fragment,输出
锁屏,输出
点亮屏幕,输出
小键盘7,转换为横屏,输出
小键盘9,转换回竖屏,输出
三、Activity中使用Fragment时两者生命周期的关系
与Activity生命周期的对比图
从图表中可以看出,活动与相应的片段在其生命周期中存在对应关系
该activity对其内部所有fragment的生命周期有直接的影响,并且在活动启动对应的方法时会引发这些碎片对象上相应功能的行为表现。例如,在活动启动onPause()方法的过程中, 这些碎片对象各自都会执行相应的onPause()操作。
相比Activity而言,Fragment还多出了几个生命周期回调方法。这些额外的方法是为了建立与Activity的交互关系而设立的。接下来将详细说明
onAttach():每当fragment被注入到activity中时会被调用(此方法可获取当前的activity)。
在为activity指定启动代码之前必须确保其能够访问fragment的布局。当activity试图访问或使用fragment时,则必须先执行此初始化步骤以获取其布局信息。
onActivityCreated()
当activity的onCreated()方法返回后调用此方法。
onDestroyView()
当fragment的layout被销毁时被调用。
onDetach()
当fragment被从activity中删掉时被调用。
一旦activity切换为resumed状态(即running状态),你就可以无需限制地添加或删除fragment。这表明,在activity处于resumed状态下,fragment能够自主运行;而其余时间则受限于activity的状态变化。
对其进行适当修改,并将其纳入当前项目中。同时记录其生命周期变化。观察它们之间的关联。
在程序运行之后, 依次执行activity.oncreate和activity.onstart. 接着调用fragment.onattach直至完成其初始化过程, 然后是activity.onresume, 最后是fragment.onresume, 并返回状态码.
单击列表中的一个项目后会跳转至第二个片段;跳转至第二个片段与活动无关;执行操作后会输出结果
点击返回键返回列表fragment,输出
单击按钮,在第二个activity中以对话框的形式显示,在activityonpause后跳转到onpause方法,并输出结果。
单击返回按钮后,在第一个 activity 中展示 activity_on resonance 的值;接着,在 fragment 随着 on resume 的变化中进行处理;最后生成结果并输出到指定位置
锁屏,输出
解锁,输出
点击home键
返回程序
按下返回键,输出
综上所述,在目前的activity生命周期内始终存在与之对应的fragment,并且该fragment的生命周期是由当前activity所决定的
四、Viewpager在是否设置缓存的情况下对两者生命周期的影响。
通过调用setOffscreenPageLimit()方法,在viewpager组件中可以设置缓存页数量,默认值设为1
工程为滑动的fragment
第一种情况:没有缓存 setOffscreenPageLimit(0)
MainActivity.java
import java.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;
//页面列表
private ArrayList
//标题列表
ArrayList
//通过pagerTabStrip可以设置标题的属性
private PagerTabStrippagerTabStrip;
private PagerTitleStrip pagerTitleStrip ;
@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);
//设置下划线的颜色
设置活动条指示器颜色为...
//设置背景的颜色
背景页条的背面表面颜色被配置为获取指定Android资源颜色常量的值
// pagerTitleStrip=(PagerTitleStrip)findViewById(R.id.pagertab);
// //设置背景的颜色
// pagerTitleStrip backgroundColor 设置为 android R color holo_blue_dark;
mfragment1 = new fragment1();
mfragment2 = new fragment2();
mfragment3 = new fragment3();
fragmentList = ** new**ArrayList
fragmentList.add(mfragment1);
fragmentList.add(mfragment2);
fragmentList.add(mfragment3);
titleList.add("第一页 ");
titleList.add("第二页");
titleList.add("第三页 ");
m_vp.setAdapter(new MyViewPagerAdapter(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{
public MyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
return fragmentList.get(arg0);
}
@Override
public int getCount() {
return fragmentList.size();
}
@Override
public CharSequencegetPageTitle(int position) {
// TODO Auto-generated method stub
return titleList.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 extends Fragment{
private ViewmMainView;
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("tag", "fragment2-->onCreate()");
LayoutInflaterinflater = getActivity().getLayoutInflater();
MainView = inflater.inflate(布局片段, (ViewGroup)获取活动并对应的视图页码器, false)
MainView = inflater.inflate(布局片段, (ViewGroup)获取活动并对应的视图页码器, false)
}
@Override
此类在构造函数中初始化了视图组件
BundlesavedInstanceState) {
Log.v("tag", "fragment2-->onCreateView()");
ViewGroupp = (ViewGroup) mMainView.getParent();
if (p !=null) {
p.removeAllViewsInLayout();
Log.v("tag","fragment2-->移除已存在的View");
}
return mMainView;
}
@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>
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"
/>
运行程序,输出:
划向第二个fragment,输出
划向第三个fragment,输出
再划回第二个fragment,输出
划回第一个fragment,输出
点击返回键退出
再将setOffscreenPageLimit设置为2,进行同样的动作
进入程序:输出
之后发现,划向任何一个fragment都没有输出
按返回键退出,输出
