【Android】Fragment的静态动态创建以及两种创建方式的生命周期

参考:

33.3-Fragment的创建-静态创建2_哔哩哔哩_bilibili

Fragment的创建_从现有代码创建foutran-CSDN博客

【Android】Fragment的基本用法、Fragment和活动间的通信、Fragment的生命周期、动态加载布局的技巧_android fragment-CSDN博客

Fragment的静态创建

  1. 创建一个Fragment
  2. 布局代码中用一个容器承接并绑定
    1. fragment标签
    2. FragmentContainView标签

先创建一个导航界面

先创建一个带按钮的空白界面吧!

img

然后创建一个Fragment

img

创建一个Activity用来承载Fragment

由于Fragment依赖于Activity存在,故而我们首先需要创建一个Activity用来承载fragment。

Be like:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity2">
    
    <fragment
        android:id="@+id/my_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.fragment.fragment.StaticFragment1"/>

</androidx.constraintlayout.widget.ConstraintLayout>

做到这一步,还并没有感觉到Fragment跟普通的Activity有什么区别,我们给fragment加点控件再看看。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".fragment.StaticFragment1">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请给我的App打分吧!"
            android:textSize="20sp"
            android:id="@+id/tv_like"/>
        
        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <RadioButton
                android:id="@+id/rb_notlike"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="不喜欢"/>
            <RadioButton
                android:id="@+id/rb_verynotlike"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="特别不喜欢"/>
        </RadioGroup>

    </LinearLayout>

    <RatingBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

img

在Fragment中完成事件的绑定

先做成这样,而后去fragment的.java文件中进行控件的绑定。

fragment的绑定其实与Activity中的绑定比较相似,在Activity中的绑定往往是:

img

在这里写或者直接用ViewBinding工具。

而在fragment中:

img

可以看到上方的onCreateView函数负责引入布局,而控件的绑定需要我们重写onViewCreated函数,大概像这样:(顺便把事件监听也写了)

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    tvlike =  view.findViewById(R.id.tv_like);
    rbDislike = view.findViewById(R.id.rb_notlike);
    rbVeryDislike = view.findViewById(R.id.rb_verynotlike);
    rbStar = view.findViewById(R.id.rating_bar);

    rbDislike.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked){
                tvlike.setText("我不喜欢这个");
            }
        }
    });
    rbVeryDislike.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked){
                tvlike.setText("我非常不喜欢这个");
            }
        }
    });
    rbStar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
        @Override
        public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
            if (fromUser) {
                Toast.makeText(getActivity(), "你给我评了"+rating, Toast.LENGTH_SHORT).show();
            }
        }
    });
}

注:这里也可以用ViewBinding进行绑定,笔者为了演示方便故而直接用的findViewById。

此时点击运行,就能正常使用啦!

在Activity中预览Fragment

我们再切换回创建的用于承载Fragment的Activity中。

img

可以看到,虽然能运行,但是预览界面中我们是看不到的。

只需要加上这句话即可

img

可以预览界面了。

注意与额外事项

关于FragmentContainerView标签

img

谷歌目前更加推荐开发者使用这个标签,专为Fragment设计,添加了一些关于生命周期销毁以及恢复的优化。

注意事项

  1. Fragment标签必须声明 android:id 属性,否则会出问题
  2. name属性可以用class属性代替

Fragment的动态创建

  1. 创建一个Fragment
  2. 布局代码中用一个容器来承接,但不直接绑定
  3. 在代码中用FragmentManager、FragmentTransaction添加Fragment到容器中

在Activity中设置一个容器

img

在Activity的代码中,设置动态创建Fragment的代码

img

public class DynamicFragmentActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_dynamic_fragment);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        if(savedInstanceState == null){
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.fragment_container_view_tag, ExampleFragment1.class,null)
                    .setReorderingAllowed(true)
                    .addToBackStack(null)
                    .commit();
        }
    }
}
  1. if(savedInstanceState == null){
    1. 这是一个条件判断语句。savedInstanceState是一个Bundle对象,通常用于保存Fragment的实例状态。如果savedInstanceState为null,说明Fragment是首次创建,而不是从保存的状态中恢复。
  2. FragmentManager supportFragmentManager = getSupportFragmentManager();
    1. 获取当前Activity的FragmentManager实例。FragmentManager用于管理Fragment的生命周期和事务。
  3. FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
    1. 创建一个Fragment事务(FragmentTransaction),用于执行添加、替换、删除Fragment等操作。
  4. fragmentTransaction.add(R.id.fragment_container_view_tag, ExampleFragment1.class,null)
    1. 向FragmentManager中添加一个新的Fragment。R.id.fragment_container_view_tag是Fragment要添加到的容器视图的ID。ExampleFragment1.class是要添加的Fragment的类。null是用于标识Fragment的标签,这里传入null表示不使用标签。
  5. .setReorderingAllowed(true)
    1. 允许Fragment事务中的视图重新排序。这通常用于动画效果,使Fragment的添加或替换看起来更平滑。
  6. .addToBackStack(null)
    1. 将这个Fragment事务添加到后退栈中。用户可以通过按后退键来返回到这个Fragment事务之前的状态。传入null表示不使用标签。
  7. .commit();
    1. 提交Fragment事务。这会触发Fragment的生命周期方法,如onCreateonStart等,并最终将Fragment显示在界面上。

两种方式创建Fragment的生命周期的区别

img

Fragment生命周期

Fragment 的生命周期主要分为以下几个阶段:

  1. onAttach(Context context)
    1. 调用时机:当Fragment被附加到Activity时。
    2. 作用:可以在这里获取Activity的引用。
  2. onCreate(Bundle savedInstanceState)
    1. 调用时机:在Fragment被创建时,通常在ActivityonCreate之后。
    2. 作用:进行初始化操作,如设置布局和初始化数据。
  3. onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    1. 调用时机:在Fragment的视图被创建时。
    2. 作用:加载和返回Fragment的视图。
  4. onViewCreated(View view, Bundle savedInstanceState)
    1. 调用时机:在Fragment的视图创建后,但在onStart之前。
    2. 作用:可以在视图已经创建但还未显示时进行一些操作。
  5. onActivityCreated(Bundle savedInstanceState)
    1. 调用时机:在ActivityonCreate方法调用后。
    2. 作用:可以访问Activity的初始化数据。
  6. onStart()
    1. 调用时机:当Fragment开始与用户交互时。
    2. 作用:开始动画或处理用户输入。
  7. onResume()
    1. 调用时机:当Fragment可见并与用户交互时。
    2. 作用:恢复之前暂停的操作。
  8. onPause()
    1. 调用时机:当Fragment不再与用户交互时。
    2. 作用:暂停动画或停止处理用户输入。
  9. onStop()
    1. 调用时机:当Fragment不再可见时。
    2. 作用:释放资源。
  10. onDestroyView()
    1. 调用时机:当Fragment的视图被销毁时。
    2. 作用:销毁视图相关的资源。
  11. onDestroy()
    1. 调用时机:当Fragment被销毁时。
    2. 作用:释放所有资源。
  12. onDetach()
    1. 调用时机:当FragmentActivity中分离时。
    2. 作用:清理与Activity的关联。

静态创建与动态创建的区别

  1. 静态创建
    1. 静态创建通常在Activity的布局文件中定义Fragment
    2. 生命周期方法按顺序调用,从onAttachonDetach
    3. 视图创建和销毁的时机与Activity的生命周期一致。
  2. 动态创建
    1. 动态创建是在代码中通过FragmentManager添加或替换Fragment
    2. 生命周期方法的调用顺序可能会有所不同,例如:
      • FragmentActivityonCreate之前被创建。
      • Fragment的视图在Activity的视图创建之后才创建。
        Activity的布局文件中定义Fragment`。
    3. 生命周期方法按顺序调用,从onAttachonDetach
    4. 视图创建和销毁的时机与Activity的生命周期一致。
  3. 动态创建
    1. 动态创建是在代码中通过FragmentManager添加或替换Fragment
    2. 生命周期方法的调用顺序可能会有所不同,例如:
      • FragmentActivityonCreate之前被创建。
      • Fragment的视图在Activity的视图创建之后才创建。
    3. 动态创建的Fragment可以被添加到不同的Activity中,并且可以多次创建和销毁。

相关推荐

  1. 创建springboot项目方式

    2024-07-20 07:44:03       33 阅读
  2. react-创建组件方式

    2024-07-20 07:44:03       33 阅读
  3. 创建线程方式,及线程生命周期

    2024-07-20 07:44:03       28 阅读
  4. 创建空List方法

    2024-07-20 07:44:03       29 阅读
  5. Golang开发:切片创建方式及区别

    2024-07-20 07:44:03       24 阅读
  6. qt创建线程方法

    2024-07-20 07:44:03       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 07:44:03       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 07:44:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 07:44:03       45 阅读
  4. Python语言-面向对象

    2024-07-20 07:44:03       55 阅读

热门阅读

  1. AI学习指南机器学习篇-t-SNE的优缺点

    2024-07-20 07:44:03       10 阅读
  2. 部署django

    2024-07-20 07:44:03       16 阅读
  3. Leetcode 202. 快乐数

    2024-07-20 07:44:03       18 阅读
  4. bug等级和优先级

    2024-07-20 07:44:03       16 阅读
  5. Perl与数据库交互:深入理解DBI模块

    2024-07-20 07:44:03       17 阅读
  6. Apache Kylin

    2024-07-20 07:44:03       12 阅读
  7. HTTP状态码(HTTP Status Code)讲解

    2024-07-20 07:44:03       17 阅读
  8. [MAUI 项目实战] 笔记App(二):数据库设计

    2024-07-20 07:44:03       18 阅读
  9. Ruby 循环

    2024-07-20 07:44:03       16 阅读