由于fragment和activity的生命周期很类似,对activity不熟悉的可以参考–深入了解Activity-生命周期,
深入理解Activity-任务,回退栈,启动模式,
概要
A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a “sub activity” that you can reuse in different activities).
一个Fragment代表了一种行为或者在一个Activity里面的一部分用户界面。你可以在一个Activity里面放置多个fragments来构建多面板的界面,也可以在多个Activity重用一个Fragment,你可以把fragment想象成一个Activity模块化的一部分。它有自己的生命周期,接受自己的输入事件,你也可以在一个Activity运行的时候动态的去添加或者移除fragment(从某种程度上说,就像一个“子Activity”,你可以使用在不同的Activity中)。
A fragment must always be embedded in an activity and the fragment’s lifecycle is directly affected by the host activity’s lifecycle. For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments. However, while an activity is running (it is in the resumed lifecycle state), you can manipulate each fragment independently, such as add or remove them. When you perform such a fragment transaction, you can also add it to a back stack that’s managed by the activity—each back stack entry in the activity is a record of the fragment transaction that occurred. The back stack allows the user to reverse a fragment transaction (navigate backwards), by pressing the Back button.
fragment总是被嵌套在activity中,它的生命周期受它所在的activity的生命周期影响。例如,当activity是暂停状态时,在activity中的fragment也是暂停状态,当activity被销毁的时候,在activity中的fragment也就被销毁。但是当activity是运行状态的时候(即resumed),你可以动态的去操作每个fragment,比如添加、移除。当你执行一个fragment事物的时候,在activity的回退栈里会维护所有发生的fragment事物。回退栈允许用户在点击回退键的时候回到上次保存的fragment。
When you add a fragment as a part of your activity layout, it lives in a ViewGroup inside the activity’s view hierarchy and the fragment defines its own view layout. You can insert a fragment into your activity layout by declaring the fragment in the activity’s layout file, as a element, or from your application code by adding it to an existing ViewGroup. However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.
当你添加一个fragment作为activity布局的一部分,它就存在于activity布局层次结构的一个ViewGroup当中,并且它可以定义它自己的布局。你可以通过在activity的布局文件当中用 来把一个fragment加入到activity当中,或者在代码中添加到ViewGroup中。fragment也可以没有用户界面。
This document describes how to build your application to use fragments, including how fragments can maintain their state when added to the activity’s back stack, share events with the activity and other fragments in the activity, contribute to the activity’s action bar, and more.
该文档表述了怎样去用fragment来构建你的应用,包括了fragment在被添加到activity的回退栈之后怎么去维护它的状态,怎样与activity、在activity中其他fragment共享事件。怎样集成action bar等等。
Design Philosophy 设计原理
Android introduced fragments in Android 3.0 (API level 11), primarily to support more dynamic and flexible UI designs on large screens, such as tablets. Because a tablet’s screen is much larger than that of a handset, there’s more room to combine and interchange UI components. Fragments allow such designs without the need for you to manage complex changes to the view hierarchy. By dividing the layout of an activity into fragments, you become able to modify the activity’s appearance at runtime and preserve those changes in a back stack that’s managed by the activity.
Android在3.0版本引入了fragment,主要是为了支持在大屏幕实现更动态更灵活的界面设计,比如平板。因为平板的屏幕比手机大,它有更多的空间来组合UI控件。fragment就是为了满足不需要去管理复杂的view层次结构这样的需求而设计的。通过在activity中放置多个fragment的,你就能够在运行时修改activity的样子并且把这些改变保存在activity维持的回退栈中。
For example, a news application can use one fragment to show a list of articles on the left and another fragment to display an article on the right—both fragments appear in one activity, side by side, and each fragment has its own set of lifecycle callback methods and handle their own user input events. Thus, instead of using one activity to select an article and another activity to read the article, the user can select an article and read it all within the same activity, as illustrated in the tablet layout in figure 1.
例如,一个新闻应用可以使用一个fragment将一列文章展示在左边,另一个fragment在右边展示内容–这样两个fragment都显示在一个activity上,每个fragment有属于自己的一系列生命周期的回调方法来处理自己的用户事件。这样就不用选择了一个文章之后再进入到另一个activity去阅读文章,用户可以在同一个activity中左边选择文章,右边阅读文章。
图1说明了这个例子。
You should design each fragment as a modular and reusable activity component. That is, because each fragment defines its own layout and its own behavior with its own lifecycle callbacks, you can include one fragment in multiple activities, so you should design for reuse and avoid directly manipulating one fragment from another fragment. This is especially important because a modular fragment allows you to change your fragment combinations for different screen sizes. When designing your application to support both tablets and handsets, you can reuse your fragments in different layout configurations to optimize the user experience based on the available screen space. For example, on a handset, it might be necessary to separate fragments to provide a single-pane UI when more than one cannot fit within the same activity.
你应该把每个fragment当作模块化的、可重用的activity组件来使用。这就是说,由于每个fragment定义了它自己的布局和行为并且拥有自己的生命周期,你可以将一个fragment放在多个activitie中使用,因为你应用重用来避免去使用一个又一个的fragment。这是非常重要的,因为模块化的fragment允许你在不同尺寸的屏幕大小上组合这些fragment。如果你要做一个同时支持平板和手机的应用的话,你可以根据不同的布局配置、可以用屏幕空间来重用你的fragment来优化用户体验。例如,在手机上可能必需把这些fragment分开放置在单一的用户界面。
Creating a Fragment 创建一个Fragment
To create a fragment, you must create a subclass of Fragment (or an existing subclass of it). The Fragment class has code that looks a lot like an Activity. It contains callback methods similar to an activity, such as onCreate(), onStart(), onPause(), and onStop(). In fact, if you’re converting an existing Android application to use fragments, you might simply move code from your activity’s callback methods into the respective callback methods of your fragment.
要创建一个fragment,你必需先创建一个Fragment类的子类(或者其他Fragment的子类)。fragment里面的代码和Activity的很类似。它也有和activity相似的回调方法,比如onCreate(), onStart(), onPause(), and onStop()。实际上,当你在转换一个已经存在的Android应用,你可能只需要把activity的回调方法中代码放入fragment的回调方法中。
Usually, you should implement at least the following lifecycle methods:
通常,你至少应该实现以下的生命周期方法:
onCreate()
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
系统在创建该fragment的时候掉用该方法。在这里你应该初始化一些fragment必要的组件,比如一些当fragment暂停或者停止的时候需要保留的组件。
onCreateView()
The system calls this when it’s time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment’s layout. You can return null if the fragment does not provide a UI.
当fragment即将第一次创建自己的用户界面时会掉用该方法,你必需返回一个View对象来构建fragment的界面。如果你返回null的话该fragment就不提供界面。
onPause()
The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed). This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).
当用户即将离开该fragment的时候该方法会被调用(即使它不总是以为着fragment要被销毁了),在该方法中我们应该保存一些需要的信息。
Most applications should implement at least these three methods for every fragment, but there are several other callback methods you should also use to handle various stages of the fragment lifecycle.
大多数应用应该在每个fragment中实现这三个方法,但是还有其他几个方法,你可以用来处理fragment生命周期多变的状态。
Handling the Fragment Lifecycle 处理Fragment的生命周期
Managing the lifecycle of a fragment is a lot like managing the lifecycle of an activity. Like an activity, a fragment can exist in three states:
管理fragment的生命与管理activity的生命周期很类似。像activity一样,fragment可以有三种状态:
Resumed
The fragment is visible in the running activity.
fragment在运行的activity中处理可见状态,并能接受用户点击事件。
Paused
Another activity is in the foreground and has focus, but the activity in which this fragment lives is still visible (the foreground activity is partially transparent or doesn’t cover the entire screen).
另外一个activity处于前台并且获取焦点,但是fragment的宿主activity仍然处于课件状态(前台activity部分透明或则没有完全覆盖整个屏幕)
Stopped
The fragment is not visible. Either the host activity has been stopped or the fragment has been removed from the activity but added to the back stack. A stopped fragment is still alive (all state and member information is retained by the system). However, it is no longer visible to the user and will be killed if the activity is killed.
fragment不在可见。它所依附的宿主activity已经停止了,并且fragment也被从activity中移除并且被添加到了回退栈中。一个stopped状态的fragment仍然存在(所有的状态和成员信息都被系统维护着)。然而,对于用户来说,是看不见它的并且如果activity被干掉的话,它也被干掉了。
Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity’s process is killed and you need to restore the fragment state when the activity is recreated. You can save the state during the fragment’s onSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), or onActivityCreated().
就像一个activity一样,你也可以用Bundle来保存fragment的状态,假设activity的进程被杀死并且你需要在activity被重新创建的时候还原fragment的状态。你可以在fragment的onSaveInstanceState()方法中保存状态,然后在onCreate(),onCreateView(), or onActivityCreated()方法中还原这些状态。
The most significant difference in lifecycle between an activity and a fragment is how one is stored in its respective back stack. An activity is placed into a back stack of activities that’s managed by the system when it’s stopped, by default (so that the user can navigate back to it with the Back button, as discussed in Tasks and Back Stack). However, a fragment is placed into a back stack managed by the host activity only when you explicitly request that the instance be saved by calling addToBackStack() during a transaction that removes the fragment.
在activity和fragment最大的不同点是各自的回退栈。当一个activity处于stopped状态的时候,它被放入一个由系统去管理的activityie回退栈。当点击回退键的时候,就会返回上个activitity。然而,fragment是被放入在由它所依附的宿主activity管理的一个回退栈。而且只有当你在一个事物里调用用addToBackStack()才会添加进去.
Caution: If you need a Context object within your Fragment, you can call getActivity(). However, be careful to call getActivity() only when the fragment is attached to an activity. When the fragment is not yet attached, or was detached during the end of its lifecycle, getActivity() will return null.
小提示: 如果你在Fragment中需要一个Context对象,你可以掉用getActivity()。然后,只有fragment被附加在一个
activity才会正常返回,否则会返回null.
好了,今天的Fragment就到这里,下一篇会讲解Fragment的其他知识。