Android中Fragment的生命周期与返回栈的管理

yizhihongxing

那么让我们来详细讲解一下“Android中Fragment的生命周期与返回栈的管理”的完整攻略。

什么是Fragment

Fragment是Android系统中重要的UI组件,它可以看做是一个子Activity,被设计成可嵌入在Activity中的组件。和Activity一样,Fragment也有自己的生命周期,包括onCreate、onCreateView、onResume等方法。并且,一个Activity可以同时包含多个Fragment。

Fragment的生命周期

Fragment的生命周期包含以下几种状态:

  • 初始化(Instantiation):创建Fragment实例,即调用构造器。
  • 加载(onAttach):Fragment依附到Activity上,此时可以通过getActivity()方法获取Activity实例。
  • 创建(onCreate):Fragment正在创建,可以通过savedInstanceState获取之前保存的状态。
  • 填充(onCreateView):创建或者加载Fragment对应的View。
  • 就绪(onViewCreated):View创建完成,可以在该方法中进行findViewById等View操作。
  • 开始(onStart):Fragment开始运行。
  • 暂停(onPause):Fragment暂停。
  • 停止(onStop):Fragment停止运行。
  • 销毁(onDestroyView):清理View资源。
  • 销毁(onDestroy):清理Fragment资源。
  • 分离(onDetach):Fragment与Activity分离。

返回栈的管理

在Activity中,我们可以通过Intent来进行Activity之间的跳转,从而实现Activity栈的管理;而在Fragment中,我们常常需要使用FragmentManager来管理Fragment栈。

FragmentManager提供了以下几个常用的方法:

  • add(int containerViewId, Fragment fragment, String tag):添加一个Fragment到栈中。
  • remove(Fragment fragment):从栈中移除一个Fragment。
  • findFragmentById(int fragmentId):通过ID查找一个Fragment。
  • popBackStack():出栈一个Fragment。
  • popBackStackImmediate():立即出栈一个Fragment。

此外,FragmentManager还提供了一些其他的方法,例如beginTransaction、commit等来对Fragment进行管理。

示例说明

我们来考虑以下两个使用示例:

示例1

在Activity中,我们添加了一个按钮,点击按钮会添加一个Fragment(对应的布局文件为fragment_test)到栈中:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.btn_add);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Fragment testFragment = new TestFragment();
                getSupportFragmentManager()
                        .beginTransaction()
                        .add(R.id.fragment_container, testFragment, "TEST")
                        .addToBackStack("TEST")
                        .commit();
            }
        });
    }
}

在Fragment中,我们重写了生命周期方法,并添加了打印信息的代码,方便我们观察生命周期的变化:

public class TestFragment extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("TestFragment", "onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("TestFragment", "onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("TestFragment", "onCreateView");
        return inflater.inflate(R.layout.fragment_test, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d("TestFragment", "onViewCreated");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("TestFragment", "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("TestFragment", "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("TestFragment", "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("TestFragment", "onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestFragment", "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("TestFragment", "onDetach");
    }
}

此时,我们运行代码,并点击按钮添加Fragment后,可以观察到生命周期变化的日志信息:

onAttach
onCreate
onCreateView
onViewCreated
onResume

随后,我们点击返回按钮,将Fragment出栈。此时的日志信息如下:

onPause
onStop
onDestroyView
onDestroy
onDetach

示例2

在Activity中,我们添加了两个按钮,分别用于添加不同的Fragment(对应的布局文件为fragment_test1和fragment_test2)。其中,第一个Fragment添加时不加入返回栈,而第二个Fragment添加时加入返回栈。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button1 = findViewById(R.id.btn_add1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Fragment testFragment = new TestFragment1();
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fragment_container, testFragment, "TEST1")
                        .commit();
            }
        });

        Button button2 = findViewById(R.id.btn_add2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Fragment testFragment = new TestFragment2();
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fragment_container, testFragment, "TEST2")
                        .addToBackStack("TEST2")
                        .commit();
            }
        });
    }
}

与上一个示例类似,我们同样重写了生命周期方法,并添加了打印信息的代码:

public class TestFragment1 extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("TestFragment1", "onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("TestFragment1", "onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("TestFragment1", "onCreateView");
        return inflater.inflate(R.layout.fragment_test1, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d("TestFragment1", "onViewCreated");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("TestFragment1", "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("TestFragment1", "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("TestFragment1", "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("TestFragment1", "onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestFragment1", "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("TestFragment1", "onDetach");
    }
}
public class TestFragment2 extends Fragment {

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d("TestFragment2", "onAttach");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("TestFragment2", "onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("TestFragment2", "onCreateView");
        return inflater.inflate(R.layout.fragment_test2, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d("TestFragment2", "onViewCreated");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("TestFragment2", "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("TestFragment2", "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("TestFragment2", "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d("TestFragment2", "onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestFragment2", "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d("TestFragment2", "onDetach");
    }
}

此时,我们运行代码,并先点击第一个按钮添加Fragment1,再点击第二个按钮添加Fragment2。随后,我们点击返回按钮,将Fragment2出栈,然后观察Fragment1的日志信息:

onAttach
onCreate
onCreateView
onViewCreated
onResume

可以发现,即使将Fragment2出栈,Fragment1的生命周期依然会继续。而如果我们此时再次点击返回按钮,将Fragment1出栈,就可以看到Fragment1的完整生命周期:

onPause
onStop
onDestroyView
onDestroy
onDetach

至此,关于Fragment的生命周期与返回栈的管理的攻略就讲解完了,希望对大家有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android中Fragment的生命周期与返回栈的管理 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Python基础教程之if判断,while循环,循环嵌套

    Python基础教程之if判断,while循环,循环嵌套攻略 本攻略将详细讲解Python中的if判断、while循环和循环嵌套的用法和示例。这些是Python编程中非常重要的基础知识,掌握它们可以帮助你编写更加灵活和高效的代码。 if判断 if判断是一种条件语句,用于根据条件的真假执行不同的代码块。它的基本语法如下: if 条件: # 条件为真时执行的代码…

    other 2023年7月28日
    00
  • vbscript Registry 注册表操作实现代码(读写删除)

    以下是使用VBScript操作注册表实现读取、写入和删除的完整攻略: 读取注册表键值 要读取注册表中的键值,可以使用GetObject函数和WScript.Shell对象的RegRead方法。示例代码如下: Set WshShell = CreateObject(\"WScript.Shell\") value = WshShell.Re…

    other 2023年10月15日
    00
  • Android程序开发之自定义设置TabHost,TabWidget样式

    Android程序开发之自定义设置TabHost,TabWidget样式攻略 在Android应用程序开发中,TabHost和TabWidget是常用的UI组件,用于创建具有多个选项卡的界面。本攻略将详细介绍如何自定义设置TabHost和TabWidget的样式。 步骤一:创建TabHost和TabWidget 首先,在XML布局文件中创建TabHost和T…

    other 2023年9月6日
    00
  • hdfs上传文件命令

    以下是“HDFS上传文件命令的完整攻略”的详细说明,包括过程中的两个示例说明。 HDFS上传文件命令的完整攻略 HDFS是Hadoop分布式文件系统,是Hadoop的核心组件之。在HDFS中,我们可以使用命令行工具来上传文件。以下是一份关于HDFS上传文件命令的完整攻略。 1. HDFS文件基础知识 在开始上传文件之前,我们需要掌握一些基础知识,例如: HD…

    other 2023年5月10日
    00
  • mybatis中嵌套查询的使用解读

    MyBatis中嵌套查询的使用解读 MyBatis是一个流行的Java持久化框架,它提供了强大的SQL映射功能。嵌套查询是MyBatis中一个重要的特性,它允许我们在一个查询中嵌套另一个查询,以便获取更复杂的结果。 嵌套查询的基本语法 在MyBatis中,我们可以使用<select>标签来定义一个嵌套查询。下面是嵌套查询的基本语法: <se…

    other 2023年7月27日
    00
  • java枚举enum和Enum类的使用

    1. 枚举(Enum)的概念 枚举(Enum)是 Java 中的一种特殊数据类型,用于定义固定数量的常量集合。枚举类型是通过关键字 enum 来定义的,一旦定义,其成员即不能再被修改。 Java 5 之前,定义常量集合一般会使用以下两种方式: 使用接口定义常量集合; 使用类定义常量集合。 这种方式的缺点是,定义很麻烦,并且容易出错。 Java 5 引入枚举之…

    other 2023年6月27日
    00
  • stm32cubemx介绍、下载与安装

    以下是关于“stm32cubemx介绍、下载与安装”的完整攻略,包括基本概念、下载安装、使用示例和注意事项。 基本概念 STM32CubeMX是STMicroelectronics公司推出的一款免费的图形化配置工具,用于快速生成STM32微控制器的初始化代码和配置文件。它可以帮助开发人员快速搭建STM32项目的基础框架,包括时钟、GPIO、中断、DMA等模块…

    other 2023年5月7日
    00
  • 目录扫描工具-dirsearch

    目录扫描工具-dirsearch 什么是目录扫描工具-dirsearch? 目录扫描工具-dirsearch是一个开源的Python编写的目录扫描工具,用于快速查找web应用程序中隐藏的目录或文件。其支持多种负载和HTTP方法,并且能够在自定义字典中使用自定义扩展名,同时也支持HTTP代理功能。 目录扫描工具-dirsearch的使用 使用目录扫描工具-di…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部