序号 | 方法名称 | 描述 |
1 |
public void onInflate(Activity activity, AttributeSet attrs,BundlesavedInstanceState)
|
在 Activity.onCreate 方法之前调用,可以获取除了 View 之外的资源
|
2 | public void onAttach(Activity activity) | 当 f ragment 第一次与 Activity 产生关联时就会调用,以后不再调用 |
3 |
public void onCreate(Bundle savedInstanceState)
|
在 onAttach 执行完后会立刻调用此方法,通常被用于读取保存的状态值,获取或者初始化一些数据,但是该方法不执行,窗口是不会显示的,因此如果获取的数据需要访问网络,最好新开线程。
|
4 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
|
作用:创建 Fragment 中显示的 view, 其中inflater 用来装载布局文件, container 表示<fragment> 标签的父标签对应的 ViewGroup 对象,savedInstanceState 可以获取 Fragment 保存的状态
|
5 | public void onViewCreated(View view, Bundle savedInstanceState) | 继上面后就会调用此方法 |
6 |
public void onActivityCreated(Bundle savedInstanceState)
|
在 Activity.onCreate 方法调用后会立刻调用此方法,表示窗口已经初始化完毕,此时可以调用控件了
|
7 | public void onStart() | 开始执行与控件相关的逻辑代码,如按键点击 |
8 |
public void onResume()
|
这是 Fragment 从创建到显示的最后一个回调的方法
|
9 | public void onPause() | 当发生界面跳转时,临时暂停,暂停时间是500ms ,0.5s 后直接进入下面的 onStop 方法 |
10 |
public void onStop()
|
当该方法返回时, Fragment 将从屏幕上消失
fragment不可见的, 可能情况:activity被stopped了 OR fragment被移除但被加入到回退栈中
|
11 |
public void onDestroyView()
|
当 fragment 状态被保存,或者从回退栈弹出,该方法被调用
|
12 |
public void onDestroy()
|
当 Fragment 不再被使用时,如按返回键,就会调用此方法
|
13 | public void onDetach() |
Fragment 生命周期的最后一个方法,执行完后将不再与 Activity 关联,将释放所有 fragment 对象和资源
|
1,当首次展示布局页面时,其生命周期方法调用的顺序是:
2,而当关闭手机屏幕或者手机屏幕变暗时,其其生命周期方法调用的顺序是:
3,当再次对手机屏幕解锁或者手机屏幕变亮时,其生命周期方法调用的顺序是:
4,而当对当前Fragment所在屏幕按返回键时,其生命周期方法调用的顺序是:
1 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onPause 2 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onStop 3 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onDestroyView 4 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onDestroy 5 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onDetach
首先,我们重写了两个Fragment,主要是重写了它们的生命周期方法,通过在其生命周期方法中打印出Log的方式来显示其方法的调用。
两个类分别是:
package
com.yeepay.fraglifecircletest.frag;
import
android.app.Activity;
import
android.app.Fragment;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
com.yeepay.fraglifecircletest.R;
public
class
FragA
extends
Fragment {
private
static
final
String TAG = FragA.
class
.getSimpleName();
@Override
public
void
onAttach(Activity activity) {
super
.onAttach(activity);
Log.i(TAG,
"onAttach"
);
}
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
Log.i(TAG,
"onCreate"
);
}
@Override
public
View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG,
"onCreateView"
);
return
inflater.inflate(R.layout.fragment_test_a,
null
,
false
);
}
@Override
public
void
onViewCreated(View view, Bundle savedInstanceState) {
Log.i(TAG,
"onViewCreated"
);
super
.onViewCreated(view, savedInstanceState);
}
@Override
public
void
onDestroy() {
Log.i(TAG,
"onDestroy"
);
super
.onDestroy();
}
@Override
public
void
onDetach() {
Log.i(TAG,
"onDetach"
);
super
.onDetach();
}
@Override
public
void
onDestroyView() {
Log.i(TAG,
"onDestroyView"
);
super
.onDestroyView();
}
@Override
public
void
onStart() {
Log.i(TAG,
"onStart"
);
super
.onStart();
}
@Override
public
void
onStop() {
Log.i(TAG,
"onStop"
);
super
.onStop();
}
@Override
public
void
onResume() {
Log.i(TAG,
"onResume"
);
super
.onResume();
}
@Override
public
void
onPause() {
Log.i(TAG,
"onPause"
);
super
.onPause();
}
@Override
public
void
onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG,
"onActivityCreated"
);
super
.onActivityCreated(savedInstanceState);
}
}
FragA.java
package
com.yeepay.fraglifecircletest.frag;
import
android.app.Activity;
import
android.app.Fragment;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
com.yeepay.fraglifecircletest.R;
public
class
FragB
extends
Fragment {
private
static
final
String TAG = FragB.
class
.getSimpleName();
@Override
public
void
onAttach(Activity activity) {
super
.onAttach(activity);
Log.i(TAG,
"onAttach"
);
}
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
Log.i(TAG,
"onCreate"
);
}
@Override
public
View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG,
"onCreateView"
);
return
inflater.inflate(R.layout.fragment_test_b,
null
,
false
);
}
@Override
public
void
onViewCreated(View view, Bundle savedInstanceState) {
Log.i(TAG,
"onViewCreated"
);
super
.onViewCreated(view, savedInstanceState);
}
@Override
public
void
onDestroy() {
Log.i(TAG,
"onDestroy"
);
super
.onDestroy();
}
@Override
public
void
onDetach() {
Log.i(TAG,
"onDetach"
);
super
.onDetach();
}
@Override
public
void
onDestroyView() {
Log.i(TAG,
"onDestroyView"
);
super
.onDestroyView();
}
@Override
public
void
onStart() {
Log.i(TAG,
"onStart"
);
super
.onStart();
}
@Override
public
void
onStop() {
Log.i(TAG,
"onStop"
);
super
.onStop();
}
@Override
public
void
onResume() {
Log.i(TAG,
"onResume"
);
super
.onResume();
}
@Override
public
void
onPause() {
Log.i(TAG,
"onPause"
);
super
.onPause();
}
@Override
public
void
onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG,
"onActivityCreated"
);
super
.onActivityCreated(savedInstanceState);
}
}
FragB.java
2 fragA = new FragA();
@Override
public
void
onClick(View v) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch
(v.getId()) {
case
R.id.button1:
if
(fragA ==
null
) {
fragA =
new
FragA();
fragmentTransaction.replace(R.id.frag_container, fragA, fragNames[
0
]);
// fragmentTransaction.addToBackStack(fragNames[0]);
}
else
{
Fragment fragment = fragmentManager.findFragmentByTag(fragNames[
0
]);
fragmentTransaction.replace(R.id.frag_container, fragment, fragNames[
0
]);
}
break
;
case
R.id.button2:
if
(fragB ==
null
) {
fragB =
new
FragB();
fragmentTransaction.replace(R.id.frag_container, fragB, fragNames[
1
]);
// fragmentTransaction.addToBackStack(fragNames[1]);
}
else
{
Fragment fragment = fragmentManager.findFragmentByTag(fragNames[
1
]);
fragmentTransaction.replace(R.id.frag_container, fragment, fragNames[
1
]);
}
break
;
default
:
break
;
}
fragmentTransaction.commit();
}
FragA生命周期调用顺序是:
此时,如果再点击另外一个按钮B,将FragB展示出来,FragA和FragB的生命周期展示方式是:
replace FragA and addToBackStack ######################################################################################## 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onAttach 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onCreate 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onCreateView 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onViewCreated 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onActivityCreated 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onStart 01-13 17:08:43.359 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onResume
可以看得出来,此时的生命周期方法调用是跟没有addToBackStack时没有任何区别的。
然后通过点击按钮B,使用FragB来替换FragA,此时FragA和FragB的生命周期方法调用顺序是:
and then replace FragB and addToBackStack &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onPause 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onStop 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onDestroyView 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onAttach 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onCreate 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onCreateView 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onViewCreated 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onActivityCreated 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onStart 01-13 17:08:46.959 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onResume
由此可以看出,FragA生命周期方法只是调用到了onDestroyView,而onDestroy和onDetach则没有被调用,这说明FragA的界面已经被销毁了,但是FragmentManager并没有完全销毁FragA,FragA依然有状态保存在FragmentManager里面。
然后再点击按钮A,使用FragA来替换当前显示的FragB,此时FragA和FragB的生命周期方法调用顺序为:
and then replace FragA again &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onPause 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onStop 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragB﹕ onDestroyView 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onCreateView 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onViewCreated 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onActivityCreated 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onStart 01-13 17:08:51.869 3102-3102/com.yeepay.fraglifecircletest I/FragA﹕ onResume
可以看到,FragB的生命方法调用顺序是跟FragB替换FragA时FragA的调用顺序一致的,作用就是只销毁了视图,但是依然保留了Fragment的状态。而此时FragA的调用则值得注意,此时FragA直接从onCreateView调起,也就是说只是重新创建了视图,而依然使用上次被替换时的Fragment状态。
OK,说到此时,是否对Fragment的生命周期方法调用在是否addToBackStack时不同有所更加深入的了解了呢?
好吧,最后一个问题。是关于Fragment在FragmentManager管理时,show和hide时的生命周期方法调用。
此时的调用实现方式为:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch
(v.getId()) {
case
R.id.button1:
hideAllFrags(fragmentTransaction);
if
(fragA ==
null
) {
fragA =
new
FragA();
fragmentTransaction.add(R.id.frag_container, fragA, fragNames[
0
]);
fragmentTransaction.addToBackStack(fragNames[
0
]);
}
else
{
fragmentTransaction.show(fragA);
}
break
;
case
R.id.button2:
hideAllFrags(fragmentTransaction);
if
(fragB ==
null
) {
fragB =
new
FragB();
fragmentTransaction.add(R.id.frag_container, fragB, fragNames[
1
]);
fragmentTransaction.addToBackStack(fragNames[
1
]);
}
else
{
fragmentTransaction.show(fragB);
}
break
;
default
:
break
;
}
fragmentTransaction.commit();
细心的话可以发现,在展示Fragment时,我们使用了方法add而非上面用的replace。而且直接addToBackStack。其实这也可以理解,你想,FragmentManager在show或者hide时,肯定是已经存在的,或者如果没有的话,需要添加进来Fragment。这便是在show和hide时,需要注意的地方,即使用add和addToBackStack方法。
在点击按钮A时,FragA的调用顺序为:
01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onAttach 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onCreate 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onCreateView 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onViewCreated 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onActivityCreated 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onStart 01-15 16:57:20.390 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onResume
可以看出没有什么不同于以上所言的部分。
然后,点击按钮B时,FragA和FragB的调用顺序为:
01-15 16:57:23.360 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags 01-15 16:57:23.360 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onAttach 01-15 16:57:23.360 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onCreate 01-15 16:57:23.360 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onCreateView 01-15 16:57:23.370 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onViewCreated 01-15 16:57:23.370 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onActivityCreated 01-15 16:57:23.370 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onStart 01-15 16:57:23.370 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onResume
可以看出,FragA并没有调用生命周期方法,这说明是展示FragB时,FragA的生命周期并没有发生变化。而FragB的生命周期与初次点击按钮A时FragA的生命周期方法相同。
然后再继续点击按钮A和B,此时打印出来的log为:
1 01-15 16:57:25.220 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags 2 01-15 16:57:44.990 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags 3 01-15 16:57:47.350 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags 4 01-15 16:57:48.020 9225-9225/com.yeepay.fraglifecircletest I/hideAllFrags﹕ hideAllFrags
这说明在FragA和FragB添加进BackStack之后无论如何地show或者hide,它们的生命周期不再发生变化。
而当屏幕上锁或变暗,然后再解锁或者变亮时,FragA和FragB的生命周期方法调用顺序为:
when screen is locked: ########################################################################################### 01-15 16:58:36.840 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onPause 01-15 16:58:36.840 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onPause 01-15 16:58:36.870 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onStop 01-15 16:58:36.880 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onStop when screen is unlocked: ########################################################################################## 01-15 17:05:01.850 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onStart 01-15 17:05:01.850 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onStart 01-15 17:05:01.870 9225-9225/com.yeepay.fraglifecircletest I/FragA﹕ onResume 01-15 17:05:01.870 9225-9225/com.yeepay.fraglifecircletest I/FragB﹕ onResume
getActivity()
方法来获得Activity的实例,然后就可以调用一些例如findViewById()之类的方法。
findFragmentById()
或者 findFragmentByTag()
.
public static class FragmentA extends ListFragment { ... // Container Activity must implement this interface public interface OnArticleSelectedListener { public void onArticleSelected(Uri articleUri); } ... }
onAttach()
方法(这个方法在fragment 被加入到activity中时由系统调用)中通过将传入的activity强制类型转换,实例化一个OnArticleSelectedListener对象:
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnArticleSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } } ... }
如果activity没有实现这个接口,fragment将会抛出ClassCastException异常,如果成功了,mListener将会是activity实现OnArticleSelectedListener接口的一个引用,所以通过调用OnArticleSelectedListener接口的方法,fragment A可以和activity共享事件。
比如,如果fragment A是ListFragment的子类,每一次用户点击一个列表项目,系统调用fragment中的onListItemClick()
方法,在这个方法中可以调用onArticleSelected()方法与activity共享事件。
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l, View v, int position, long id) { // Append the clicked item's row ID with the content provider Uri Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id); // Send the event and Uri to the host activity mListener.onArticleSelected(noteUri); } ... }