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

那么让我们来详细讲解一下“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定义变量类型

    Python定义变量类型攻略 在Python中,变量类型是根据变量的值来确定的,而不是根据变量的声明来确定的。这意味着你可以在任何时候改变变量的类型。下面是关于Python定义变量类型的完整攻略。 1. 整数类型(int) 整数类型用于表示整数值,可以是正数、负数或零。在Python中,整数类型是没有大小限制的,可以表示任意大的整数。 示例1: x = 10…

    other 2023年8月8日
    00
  • [转] ElasticSearch 常用的查询过滤语句

    [转] ElasticSearch 常用的查询过滤语句 欢迎大家来到本篇文章。本文将介绍 ElasticSearch 常用的查询过滤语句,希望能够帮助大家更好地了解 ElasticSearch 的使用方法。 Query String Query Query String Query 是 ElasticSearch 中最常见的查询语句之一,它可以根据指定的搜索…

    其他 2023年3月28日
    00
  • Net内存管理五大基础

    Net内存管理五大基础攻略 1. 内存分配与释放 在Net内存管理中,正确的内存分配和释放是非常重要的。以下是一些基本的步骤和示例说明: 步骤1: 确定需要分配的内存大小和类型。 步骤2: 使用适当的内存分配函数来分配内存,如malloc或new。 步骤3: 检查内存分配是否成功。如果分配失败,需要处理错误情况。 步骤4: 使用分配的内存进行操作。 步骤5:…

    other 2023年8月1日
    00
  • Unix系统中文件管理和文件权限设置教程

    Unix系统中文件管理和文件权限设置教程 文件管理基础 Unix系统中的文件可以分为普通文件和目录文件两种,二者的区别在于目录文件可包含多个文件和子目录文件。Unix系统中,每个文件和目录都有一个唯一的路径描述符,用于指定文件或目录的位置及名称。 文件和目录名称 Unix系统中的文件和目录名称可以是任意字符,但通常建议只使用字母、数字和少数特殊字符(如“-”…

    other 2023年6月27日
    00
  • Skype账户登录时提示“无法识别登录信息,请检查Skype用户名和密码”的解决办法

    以下是Skype账户登录时提示“无法识别登录信息,请检查Skype用户名和密码”的解决办法: 1. 检查用户名和密码是否正确 第一步,我们需要确保输入的用户名和密码没有错误。请注意区分大小写。 如果用户名和密码不正确,则会提示“无法识别登录信息,请检查Skype用户名和密码”。此时,我们需要重新输入正确的用户名和密码尝试登录。 举个例子,如果您的Skype用…

    other 2023年6月27日
    00
  • 统信uos系统怎么管理打印界面和打印队列?

    打印界面管理 在统信uos系统中,打印界面管理主要包括设置打印机和打印参数等相关操作。具体步骤如下: 进入系统设置,在“打印管理”中选择“打印机”,添加或编辑打印机,设置打印机名称、型号等基本信息,确认后保存。 打开“打印机”界面,选择要使用的打印机,点击“属性”,设置打印参数,如纸张大小、打印质量、双面打印等,确认后保存。 示例1:在统信uos系统中,用户…

    other 2023年6月27日
    00
  • React通过classnames库添加类的方法

    React通过classnames库添加类的方法攻略 1. 安装classnames库 首先,在项目中安装classnames库。可以通过以下命令使用npm进行安装: npm install classnames 2. 导入classnames库 在React组件中,需要导入classnames库,以便在添加类名时使用。可以使用import语句将classn…

    other 2023年6月28日
    00
  • Android 类似微信登录输入框效果

    当你想要实现类似微信登录输入框效果的时候,可以按照以下步骤进行操作: 创建布局文件:首先,创建一个XML布局文件,用于定义登录界面的外观和组件。可以使用LinearLayout或者RelativeLayout等布局容器来放置输入框和按钮等组件。 示例代码: <LinearLayout xmlns:android=\"http://schema…

    other 2023年9月7日
    00
合作推广
合作推广
分享本页
返回顶部