【Android】Fragment碎片的动态与静态创建,生命周期及常用操作总结
文章目录
介绍
在Fragment之前,我们通常把一个Activity作为一个页面。
但随着页面元素的增加以及场景的复杂,单个页面已经不能满足需要,在屏幕上通常要同
时展示多个区域、多个页面内容,这些内容的切换通常是整体的。
因此,为了让屏幕展示更多内容,以及对这些内容统一管理,引入了Fragment。
- Fragment,就是将一块内容区域封装在一起,统一管理,构成一个Fragment。
- Fragment是依附在Activity上而存在的。一个Activity中可以有多个Fragment,各个Fragment之间可以传递数据、互相切换。
- Fragment与Activity很相似,也有生命周期函数
设置环境
在应用的 build.gradle 文件中添加以下依赖项:
dependencies {
val fragment_version = "1.8.1"
// Java language implementation
implementation("androidx.fragment:fragment:$fragment_version")
// Kotlin
implementation("androidx.fragment:fragment-ktx:$fragment_version")
}
创建
静态创建
- 创建 Fragment 类及其布局文件。
- 在活动的布局文件中使用
<androidx.fragment.app.FragmentContainerView>或fragment标签引用 Fragment。
注意使用的是androidx.fragment.app.Fragment
具体流程:
创建 Fragment 类及其布局文件
-
自动生成了
ExampleFragment类及其布局文件这是一个自定义的类继承自
Fragment,你可以在这个类中定义 fragment 的行为和 UI。

在活动的布局文件中添加 Fragment
- 新建一个类(比如
MainActivity),因为fragment需要依赖于activity。在该类的布局文件中添加Fragment容器视图(或者使用FragmentContainerView容器也可以)
- 注意添加
android:name或class属性来指定要加载的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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".fragment.StaticFragment1">
<!-- 添加一个fragment,用于显示StaticFragment类的实例 -->
<!-- 通过android:name属性指定fragment的类名 -->
<!-- 通过android:id属性为fragment指定一个ID,以便在代码中引用 -->
<fragment
android:id="@+id/fragment"
android:name="com.example.fragmentpractice_726.fragment.exampleFragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_example1"/>
<!-- 或者使用 FragmentContainerView -->
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.fragmentpractice.fragment.ExampleFragment" />
</LinearLayout>
使用 Fragment
- 在
ExampleFragment类的布局文件中设计UI,并在ExampleFragment类中设置交互逻辑
注意
fragment标签和FragmentContainerView标签
-
fragment必须声明android:id或者android:tag属性,否则会有错 -
FragmentContainerView必须声明android:id属性 -
tools:layout = "@layout/example fragment",可在预览视图中看到fragment预览界
面 -
android:name属性也可以用class代替,
class="com.example.fragmentpractice.fragment.StaticFragment1"
动态创建
- 创建
Fragment类及其布局文件- 在
Activity的布局文件中准备容器- 在
Activity中动态添加Fragment
创建Fragment类及其布局文件
在Activity的布局文件中准备容器
可以使用FragmentContainerView或FrameLayout
设置一个id,以便动态创建获取
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
在Activity中动态添加Fragment
使用FragmentManager、FragmentTransaction将Fragment添加到Activity中
Fragment Manager:
每个 Activiy 都有一个 FragmentManager,用来管理它所包含的 Fragment。在使用支持库时,将使用getSupportFragmentManger 方法来访问FragmentManager
Fragment Transaction:
FragmentTransaction用于添加、删除和替换Fragment。使用Fragment Transaction,可以使布局具有动态性
也就是说,它们将根据用户交互和应用状态进行调整和更改。
使用 Fragment Manager 的beginTransaction 方法创建新的 Fragment Transaction
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
// 检查是否是第一次创建Activity实例,防止重复添加Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
// 获取FragmentManager以管理Fragments
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// 开启一个Fragment事务,以添加、移除或替换Fragment
fragmentTransaction.add(R.id.fragment_container2, ExampleFragment2.class, null);
// 将ExampleFragment2添加到指定的容器(R.id.fragment_container2)
// 第一个参数是Fragment容器的ID
// 第二个参数是Fragment类
// 第三个参数是传递给Fragment的可选参数,这里为null
fragmentTransaction.commit();
// 提交Fragment事务,应用所有更改
}
}
}
生命周期
尽管 Fragment 的生命周期与其所属的 Activity 相关,但它在标准 Activity 生命周期中也有自己的特点。它包括基本的 Activity 生命周期方法,例如 onResume ,但与 Activity 交互和 UI 生成相关的方法也很重要。
被调用以将fragment恢复到恢复状态(与用户交互)的一系列核心生命周期方法是:
onAttach一旦fragment与其活动关联,就会调用。onCreate被调用来初始创建fragment。onCreateView创建并返回与fragment关联的视图层次结构。onViewCreated可以在视图已经创建但还未显示时进行一些操作onActivityCreated在Activity的onCreate方法调用后onStart使fragment对用户可见(基于其包含的活动正在启动)。onResume使fragment开始与用户交互(基于其包含的活动正在恢复)。
当fragment不再被使用时,它会经历一系列相反的回调:
onPausefragment不再与用户交互,因为其活动已暂停或fragment操作正在活动中对其进行修改。onStopfragment不再对用户可见,因为其活动已停止或fragment操作正在活动中修改它。onDestroyView允许fragment清理与其视图关联的资源。onDestroy调用以对fragment状态进行最终清理。onDetach在fragment不再与其活动关联之前调用。
Fragment操作
添加
一个容器里可以添加多个Fragment,依次盖在上面,类比FrameLayout
注意:由于事件分发机制,同时添加多个
Fragment时,在空白处点击会产生穿透的效果,也就是作用到下层的Fragment。解决方法:在
Fragment里拦截onTouch事件。
- 最好不要用
add方式,而用replace添加fragment,保证容器中里只有一个Fragment
添加的方法:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- 使用
Fragment的类名来添加Fragment并且添加到回退栈中
fragmentTransaction.add(R.id.fragment_container2, ExampleFragment2.class, null).addToBackStack(null).commit();
- 使用
Fragment实例添加Fragment
ExampleFragment2 fragment2 = new ExampleFragment2();
fragmentTransaction.add(R.id.fragment_container2, fragment2).addToBackStack(null).commit();
返回栈:
点击手机的back按钮会依次弹出BackStack中的Fragment,而不是直接退出Activity。
addToBackStack()参数:是用于标记回退栈中的事务的标签。这个标签可以用于以后对回退栈中事务的查找和管理。不是返回栈的名字
传递
null,则不会对事务进行标记。这个事务会被简单地添加到回退栈中。
查找
-
根据
id查找Fragment fragment = fragmentManager.findFragmentById(R.id.fragment);findFragmentById方法根据提供的id查找Fragment。- 如果找到多个
Fragment,它将返回最上面的一个。
-
根据
tag查找Fragment fragment = fragmentManager.findFragmentByTag("fragment");findFragmentByTag方法根据提供的tag查找Fragment。- 如果有多个
Fragment使用相同的标签,它将返回最上面的一个。
查找逻辑
- 如果
Fragment没有在当前容器中找到,它会继续在回退栈(BackStack)中查找。- 回退栈中的
Fragment是按照添加顺序存储的,findFragmentById和findFragmentByTag方法会返回最上面的一个。- 如果
Fragment不在当前容器和回退栈中,方法会返回null。
删除
fragmentTransaction.remove(fragment).commit();。
该方法不会将
Fragment从回退栈中移除,Fragment的状态仍然保留在回退栈中。只有按返回键或调用FragmentManager的popBackStack方法,Fragment才会被彻底移除。
替换
使用 FragmentTransaction 的 replace 方法可以用新的 Fragment 替换当前容器中的 Fragment。这会先移除当前容器中所有的 Fragment,然后添加新的 Fragment。
fragmentTransaction.replace(R.id.fragment_container, ReplaceFragment.class, null).commit();
移除当前容器中所有的
Fragment,然后添加新的Fragment
带回退栈情况
fargment移除了,但回退栈没有移除,使用返回键界面不会变化
- 如果你使用
replace方法,默认情况下,新添加的Fragment会覆盖旧的Fragment。 - 可以使用
addToBackStack方法将replace操作添加到回退栈中,这样用户可以通过按返回键回到之前的Fragment。
示例:使用 replace 和 addToBackStack
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null); // 将事务添加到回退栈
transaction.commit();
显示与隐藏
fragmentTransaction.show(yourFragment).commit();
fragmentTransaction.hide(yourFragment).commit();
fragmentTransaction.attach(yourFragment).commit();
fragmentTransaction.detach(yourFragment).commit();
| 操作 | Fragment的变化 |
|---|---|
| Show/Hide | 仅隐藏或显示View,Fragment的状态和实例保持不变 |
| Attach/Detach | 仅销毁View,Fragment仍保存状态,不与Activity关联,允许后续重新显示。 |
| Add/Remove | 销毁View和整个Fragment,使其状态完全消失,不可恢复 |
-
Show/Hide:适用于需要频繁切换显示的用户界面,比如标签页。
-
Attach/Detach:适用于当Fragment需要暂时不可见,但不想重新创建的情形。
-
Add/Remove:在需要管理Fragment的生命周期和状态,且Fragment的使用是可选的场景最为合适。
ew,Fragment的状态和实例保持不变 |
| Attach/Detach | 仅销毁View,Fragment仍保存状态,不与Activity关联,允许后续重新显示。 |
| Add/Remove | 销毁View和整个Fragment,使其状态完全消失,不可恢复 | -
Show/Hide:适用于需要频繁切换显示的用户界面,比如标签页。
-
Attach/Detach:适用于当Fragment需要暂时不可见,但不想重新创建的情形。
-
Add/Remove:在需要管理Fragment的生命周期和状态,且Fragment的使用是可选的场景最为合适。
感谢您的阅读
如有错误烦请指正
参考:
1.1-Activity通过方法向Fragment传递数据_哔哩哔哩_bilibili
2. 《第一行代码》
更多推荐



所有评论(0)