Android温故知新之Fragment篇(一) Fragment生命周期

夜深了,又到了撸代码的时间,其实一直想把以前学的东西总结一下,看看有哪些疏漏和误解的地方,从这里开始开一个复习系列,当然对于很多刚学习安卓的同学,这应该是一个入门系列。
开始第一章,片段。

为什么是片段而不是活动呢?因为活动的基础回调和基础使用很简单,源码又很难,而且涉及启动模式,状态保存等等,等笔者找到一个能贯穿的平衡点,会单独开一篇活动专题复习。

安卓深入哪一块其实都不简单,所以片段也只讲重点,点到为止。

初次导入片段时需要选择导哪个包的,有如下两个选择

android.support.v4.app.Fragment
android.app.Fragment;

support.v4.app下的片段具有更好的兼容性,可以兼容到1.6版本,而应用下的片段只支持3.0以上的版本,如果minsdk设置在3.0以上,当然用哪个都可以,如果需要兼容到3.0以下,建议使用V4包下的片段。

划重点1: support.v4.app下的片段可以兼容到1.6版本,且support.v4.app下的片段和应用下的片段不具有继承关系,无法进行类型转换。

笔者以 support.v4.app 下的片段为例,正式开始今天的学习。

首先创建MyFragment:

MyFragment.java

 
 
public class MyFragment extends Fragment {
    private static final String TAG =“MyFragment--”;
    @Override
    public void onInflate(Context context,AttributeSet attrs,Bundle savedInstanceState){
        super.onInflate(context,attrs,savedInstanceState);
        Log.d(TAG,“onInflate:执行”);
    }

    @Override
    public void onAttach(Context context){
        super.onAttach(context);
        Log.d(TAG,“onAttach:执行”);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: 执行");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView: 执行");
        View view = inflater.inflate(R.layout.fragment_my,container,false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated: 执行");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart: 执行");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: 执行");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause: 执行");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop: 执行");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView: 执行");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: 执行");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach: 执行");
    }
}


fragment_my.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width = “match_parent”
        android:layout_height = “match_parent”
        android:text= “fragment”/>
</RelativeLayout>

然后创建承载片段的活性:

MyActivity.java

public MyActivity extends AppCompatActivity {
    private static final String TAG =“MyActivity ++”;
    @Override
    protected onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate:执行");
        Log.d(TAG,"setContentView:执行前");
        setContentView(R.layout.activity_my);
        Log.d(TAG,"setContentView:执行后");
    }

    @Override
    protected onStart(){
        super.onStart();
        Log.d(TAG,"onStart:执行");
    }

    @Override
    protected onStop(){
        super.onStop();
        Log.d(TAG,"onStop:执行");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: 执行");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause: 执行");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: 执行");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart: 执行");
    }
}

activity_my.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns: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="com.tustcs.ndktest.MyActivity">
    <fragment
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:id = "@+id/my_fragment"
        class= "com.tustcs.ndktest.MyFragment"/>
</RelativeLayout>

运行程序,启动时输出如下

可以发现,onInflate,onAttach,的onCreate,onCreateView,onActivityCreated这四个方法都发生在给活动设置视图的时候,在onStart,的onResume分别与活动的调用onStart,的onResume对应。

点击回键后,销毁过程如下


销毁过程中片段的的onPause,的onStop分别和活动的的onPause,的onStop相对应,onDestroyView,onDestory,onDetach发生在活动的的onDestroy方法中。并且和活性一样,片段的生命周期方法也是成对出现的,按什么顺序创建就按它的逆序销毁。

我们又可以搬出那张经典的图:


没错,这里少了onInflate方法,onInflate只有在通过<片段>标签添加片段时才会调用。

public void onInflate(上下文上下文,AttributeSet attrs,Bundle savedInstanceState) 

注意onInflate的第二个参数和第三个参数,熟悉自定义视图的人对AttrbuteSet一定非常熟悉,这是搜索获取XML值的关键,所以在其方法内,可以读取到其XML中的属性值,通过第三个参数可以保存状态。

通过

public class MyActivity extends AppCompatActivity {
    private static final String TAG = "MyActivity++";
    private MyFragment myFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: 执行");
        super.onCreate(savedInstanceState);

        Log.d(TAG, "setContentView: 执行前");
        setContentView(R.layout.activity_my);
        Log.d(TAG, "setContentView: 执行后");

        myFragment = new MyFragment();
        android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(myFragment,"aaa");
        ft.commit();
    }

运行结果如下:

动态添加Fragment不会调用onInflate。


至于为什么一张图就能总结的东西,笔者还是敲了一堆代码去验证,或许这就是计算机的学习之路,实践出真知,就像笔者曾在一本书中介绍说Fragment的onInflate会在Activity的onCreate之前调用,经过亲自验证才发现并不是如此,至少不在所有版本的SDK中都是这样执行,多动动手总会有收获。

猜你喜欢

转载自blog.csdn.net/l_scag/article/details/80343782
今日推荐