欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

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

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

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

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

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>

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

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

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

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

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

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

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

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

没错,这里少了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();
    }

运行结果如下:

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

动态添加Fragment不会调用onInflate。


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