掌握Android Fragment开发之魂:Fragment的深度解析(下)
在上一篇文章中,我们深入探讨了Fragment 通信,包含Fragment 向 Activity 传递数据、Activity 向 Fragment 传递数据、Fragment 之间的通信方式。感兴趣的朋友,请前往查阅: 掌握Android Fragment开发之魂:Fragment的深度解析(中) 。
在这篇文章中,我们将继续深入探讨 Android Fragment,包括以下几个核心主题:
-
DialogFragment 是什么
-
DialogFragment相比 Dialog的优势
-
DialogFragment 的使用方式
-
Fragment 在 Android 开发中的最佳实践
一、DialogFragment 的魅力所在
1、DialogFragment 是什么?
DialogFragment
是 Android 开发中用于创建和管理对话框的一个类,它是 Fragment
的一个子类,专门用于显示对话框界面。在 Android 中,对话框是一种浮动的 UI 元素,通常用于提供额外的信息或选项,而不会干扰用户当前的操作。
以下是 DialogFragment
的一些关键特点:
-
模态性:
DialogFragment
通常以模态的形式出现,意味着用户必须与对话框交互(如确认或取消操作)才能返回到应用程序的其他部分。 -
生命周期:
DialogFragment
拥有自己的生命周期,与宿主Activity
的生命周期相互独立。它在onCreate
方法中初始化,在onCreateView
方法中创建视图,在onShow
方法中显示,在onDismiss
方法中关闭。 -
自定义视图:开发者可以在
onCreateView
方法中定义自己的布局文件,从而实现高度自定义的对话框界面。 -
显示与隐藏:可以通过调用
show
方法将DialogFragment
显示在宿主Activity
上,也可以调用dismiss
方法将其隐藏。 -
主题和样式:可以为
DialogFragment
设置不同的主题和样式,以适应不同的 UI 设计需求。 -
交互:
DialogFragment
可以包含按钮、列表、文本框等 UI 组件,允许用户进行交互。 -
BackStack:当
DialogFragment
被添加到FragmentTransaction
时,可以选择是否将其添加到回栈(BackStack)中,这允许用户通过按返回键来导航。
2、DialogFragment相比 Dialog的优势
DialogFragment
相比于传统的 Dialog
有以下几个优势:
-
生命周期可控
DialogFragment
拥有自己的生命周期,能够更好地与
Activity和
Fragment的生命周期进行协同。当
Activity被销毁时,与之关联的
DialogFragment` 也会被销毁,这有助于避免内存泄漏。 -
UI更新
DialogFragment` 可以更容易地响应配置更改(如屏幕旋转),在这些情况下,对话框可以保持其状态,而不需要重新创建。
-
BackStack 管理
DialogFragment
可以被添加到 Fragment 的回栈(BackStack)中,这意味着用户可以使用返回键来关闭对话框,提供了更好的用户体验。 -
样式和主题
DialogFragment
允许开发者通过设置不同的主题和样式来自定义对话框的外观,这在传统的Dialog
中实现起来可能更加困难。 -
兼容性
随着 Android 系统的更新,
DialogFragment
能够更好地适应新的 UI 设计和交互模式,而传统的Dialog
可能需要更多的工作来保持兼容性。 -
代码复用,解耦设计
DialogFragment
允许开发者创建可复用的对话框模板,可以在不同的Activity
中重复使用,而不需要为每个Activity
编写相同的代码。 -
与 Fragment 协同
如果你的应用程序已经使用了
Fragment
来管理 UI 的不同部分,使用DialogFragment
可以保持代码的一致性,并且可以更容易地在Fragment
之间共享数据。 -
动画和转场支持
DialogFragment` 支持自定义的进入和退出动画,这使得对话框的显示和隐藏可以有更丰富的视觉效果。
-
更清晰的代码结构
使用
DialogFragment
可以使代码结构更加清晰,因为每个对话框都是一个独立的实体,拥有自己的逻辑和布局。 -
支持 Fragment 事务
DialogFragment` 可以作为 Fragment 事务的一部分进行管理,这使得在运行时添加、替换或删除对话框变得更加容易。
-
丰富的回调
DialogFragment 提供了更多的回调方法,如
onCreateDialog()
、onResume()
等。
总的来说,DialogFragment
提供了更好的生命周期管理、更灵活的 UI 更新、更丰富的自定义选项以及更好的用户体验,这些优势使其成为在 Android 应用中创建和管理对话框的首选方式。
3、DialogFragment 的使用方式
接下来,我们通过一个示例来演示 DialogFragment 的使用方式。
public class MyDialogFragment extends DialogFragment {@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());builder.setTitle("标题").setMessage("这是一个 DialogFragment").setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 处理确定按钮点击事件}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 处理取消按钮点击事件}});return builder.create();}
}
要显示该 DialogFragment,只需要在 Activity 中执行以下代码:
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 显示 DialogFragmentshowDialogFragment();}private void showDialogFragment() {MyDialogFragment dialogFragment = new MyDialogFragment();dialogFragment.show(getSupportFragmentManager(), "MyDialogFragment");}
}
在 MainActivity
中,我们首先实例化 MyDialogFragment
。然后,调用 show()
方法并传入 FragmentManager
实例和一个可选的标签(用于标识该 DialogFragment)来显示该 DialogFragment。
show()
方法的完整签名如下:
public void show(@NonNull FragmentManager manager, @Nullable String tag)
manager
: 用于管理 Fragment 的 FragmentManager 实例。tag
: 可选的字符串标签,用于标识该 DialogFragment。如果你需要在将来获取该 DialogFragment 的实例,可以使用这个标签。
在上面的示例中,我们使用 getSupportFragmentManager()
获取 FragmentManager
实例,并将标签设置为 “MyDialogFragment”。
你还可以通过 DialogFragment
的其他方法来自定义对话框的样式和行为,例如:
setStyle()
: 设置对话框的样式(默认、全屏等)。setCancelable()
: 设置对话框是否可以通过点击外部区域或按下返回键来取消。setShowsDialog()
: 控制是否显示对话框标题和按钮。
通过上述代码和扩展方法,你就可以灵活地创建和管理 DialogFragment 了。DialogFragment 不仅提供了标准的 Fragment 生命周期管理,还增强了对话框的可定制性,是展示模态界面的绝佳选择。
二、Fragment 在 Android 开发中的最佳实践
在 Android 应用程序开发中,合理使用 Fragment 可以带来诸多好处,提高代码的可维护性和用户体验。因此,掌握 Fragment 的最佳实践是非常有必要的。
1、保持 Fragment 精简
Fragment 被设计为可重用的界面构建块,因此应该保持其职责单一、逻辑精简。
将过多的业务逻辑耦合到 Fragment 中会增加其复杂性,影响可维护性。
相反,应该将业务逻辑分离到其他层次,如 ViewModel 或 Repository,而让 Fragment 专注于界面呈现和用户交互。
2、高度解耦设计
遵循单一责任原则,Fragment 应该与其他组件(如 Activity、ViewModel 等)高度解耦。
这种解耦设计可以最大限度地提高代码的可复用性和可测试性。
例如,可以通过定义接口或使用依赖注入等方式来降低 Fragment 与其他组件的耦合度。
3、避免过度嵌套
虽然 Fragment 可以嵌套,但过度嵌套会导致界面层次过深,增加复杂性和性能开销。
因此,应该权衡利弊,尽量保持 Fragment 嵌套的层次浅一些。
如果确实需要嵌套,可以考虑使用 ViewPager 等容器来管理多个 Fragment。
4、注意生命周期管理
Fragment 具有自己的生命周期,与其宿主 Activity 的生命周期存在一定的联系。
在编写 Fragment 代码时,需要特别注意生命周期方法的调用顺序和时机,避免出现内存泄漏或数据丢失等问题。
同时,也要注意在适当的生命周期方法中执行相应的操作,如数据加载、视图绑定等。
public class MyFragment extends Fragment {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 初始化操作}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 加载布局return inflater.inflate(R.layout.fragment_my, container, false);}@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);// 初始化视图组件}@Overridepublic void onDestroyView() {super.onDestroyView();// 清理操作,如取消动画、移除监听器等}@Overridepublic void onDestroy() {super.onDestroy();// 最终清理操作}
}
5、利用 FragmentManager 的力量
FragmentManager 是管理 Fragment 生命周期和事务的核心组件。
掌握 FragmentManager 的使用技巧,如 add()
、replace()
、remove()
、addToBackStack()
等方法,可以更好地控制 Fragment 的行为,可以确保 UI 更新的一致性。
同时,也要注意合理利用回退栈,为用户提供流畅的导航体验。
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, new MyFragment()); // 替换 Fragment
transaction.addToBackStack(null); // 添加到回栈
transaction.commit(); // 提交事务
6、避免在 Fragment 中进行长时间运行的操作
长时间运行的操作应该在后台线程中执行,以避免阻塞主线程。
new AsyncTask<Void, Void, Void>() {@Overrideprotected Void doInBackground(Void... voids) {// 长时间运行的操作return null;}@Overrideprotected void onPostExecute(Void aVoid) {// 更新 UI}
}.execute();
7、使用 setUserVisibleHint
来优化性能
这个方法可以帮助了解 Fragment 是否对用户可见,从而优化性能。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);if (isVisibleToUser) {// 当 Fragment 对用户可见时执行的操作}
}
8、正确处理 Fragment 回栈
当用户按下返回键时,确保正确处理 Fragment 回栈,提供一致的用户体验。
@Override
public void onBackStackChanged() {super.onBackStackChanged();if (getFragmentManager().getBackStackEntryCount() == 0) {// 处理回栈为空的情况,如退出 Activity}
}
9、使用 Fragment
的 newInstance
方法
这是一种创建 Fragment 实例的推荐方式,它使得传递参数变得更加容易。
复制
public static MyFragment newInstance() {MyFragment fragment = new MyFragment();Bundle args = new Bundle();// 向 args 中添加参数fragment.setArguments(args);return fragment;
}
10、避免内存泄漏
确保在 onDestroy
或 onDestroyView
中清理资源,如移除监听器、取消动画等。
@Override
public void onDestroyView() {super.onDestroyView();if (someListener != null) {someView.removeOnClickListener(someListener);someListener = null;}
}
11、使用 LoaderManager
进行数据加载
使用 LoaderManager
可以帮助你管理后台数据加载,并在 Fragment 重新创建时恢复加载状态。
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getLoaderManager().initLoader(0, null, this);
}@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {// 创建并返回数据加载器
}@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {// 数据加载完成,更新 UI
}@Override
public void onLoaderReset(Loader<Cursor> loader) {// 数据加载器被重置,清理数据
}
通过上述最佳实践,我们能够更高效地管理 Fragment,提升应用的稳定性和性能,可以帮助你创建更加健壮且易于维护的 Android 应用。
相关文章:
掌握Android Fragment开发之魂:Fragment的深度解析(下)
在上一篇文章中,我们深入探讨了Fragment 通信,包含Fragment 向 Activity 传递数据、Activity 向 Fragment 传递数据、Fragment 之间的通信方式。感兴趣的朋友,请前往查阅: 掌握Android Fragment开发之魂:Fragment的深度…...

小巧简单实用的Linux端口转发工具Rinetd
Linux下实现端口转发有很多种方法,尤其是在可以联网的情况下,更是容易。最近在资源受限的定制系统中,找到一个方便离线安装和使用的端口转发工具Rinetd,安装包仅几十K,而且有很多版本的Linux发行系统的支持。 1、安装…...

HackBar 新手使用教程(入门)
啥是Hackbar? Hackbar是一个Firefox 的插件,它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其它变化的影响。 有网址的载入于访问,联合查询,各种编码,数据加密功能。 这个Hackbar可以帮助你在测试SQL注入,XSS漏洞和网站的安全性,主要是帮助…...

<Linux> 权限
目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组umask粘滞位 权限 权限是操作系统用来限制对资源访问的机制,权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组,通过这样的机制来限制哪些用户、哪些组可以…...

Nacos Docker 快速部署----解决nacos鉴权漏洞问题
Nacos Docker 快速部署 1. 说明 1.1 官方文档 官方地址 https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html docker启动文件的gitlhub地址 https://github.com/nacos-group/nacos-docker.git 问题: 缺少部分必要配置与说明 1.2 部署最新版本Nacos&…...

存储或读取时转换JSON数据
一、 数据库类型 二、使用Hutool工具 存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题: 原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject 三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器 package …...
Spring Data JPA的作用和用法
Spring Data JPA 是 Spring 框架的一个模块,它提供了一种数据访问抽象,允许以一种声明式和简洁的方式来处理数据库操作。它基于 Java Persistence API (JPA),是一个行业标准的 ORM(对象关系映射)规范,用于将…...

【go项目01_学习记录08】
学习记录 1 模板文件1.1 articlesStoreHandler() 使用模板文件1.2 统一模板 1 模板文件 重构 articlesCreateHandler() 和 articlesStoreHandler() 函数,将 HTML 抽离并放置于独立的模板文件中。 1.1 articlesStoreHandler() 使用模板文件 . . . func articlesSt…...

Java中的线程
一、创建线程的几种方式? ① 通过继承Thread类并重写run方法 ,实现简单但不可以继承其他类 Thread底层也是实现了Runnable接口,重写的是run而不是start方法 ②实现Runnable接口并重写run方法, 避免了单继承的局限性ÿ…...
顺序表的实现(迈入数据结构的大门)(完整代码)
seqlist.h #pragma once typedef int SLDataType;#include<stdio.h> #include<stdlib.h> #include<assert.h>typedef struct SeqList {SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量 }SL;//初始化和销毁 void SLInit(SL* ps); void SL…...

neo4j-5.11.0安装APOC插件or配置允许使用过程的权限
在已经安装好neo4j和jdk的情况下安装apoc组件,之前使用neo4j-community-4.4.30,可以找到配置apoc-4.4.0.22-all.jar,但是高版本neo4j对应没有apoc-X.X.X-all.jar。解决如下所示: 1.安装好JDK与neo4j 已经安装对应版本的JDK 17.0…...
mybatis 中 #{}和 ${}的区别是什么?
在 MyBatis 中,#{} 和 ${} 是两种用于参数替换的语法,但它们之间存在一些重要的区别,主要体现在安全性、预编译和动态 SQL 上。 安全性: #{}:这是预编译处理,MyBatis 会为传入的参数生成 PreparedStatement…...
深入解析C#中的接口设计原则
深入解析C#中的接口设计原则 目录 深入解析C#中的接口设计原则 一、接口设计的SOLID原则 二、接口设计的最佳实践 三、接口设计的高级技术 四、结论 接口在面向对象编程中扮演着至关重要的角色。它们是定义行为契约的一种方式,允许实现者提供这些行为的具体实现…...

106短信群发平台在金融和法务行业的应用分析
一、金融行业应用 1.客户通知与提醒:银行、证券、保险等金融机构经常需要向客户发送各类通知和提醒,如账户余额变动、交易确认、扣费通知、理财产品到期提醒等。106短信群发平台可以快速、准确地将这些信息发送到客户的手机上,确保客户及时获…...

Spring AOP(2)
目录 Spring AOP详解 PointCut 切面优先级Order 切点表达式 execution表达式 切点表达式示例 annotation 自定义注解MyAspect 切面类 添加自定义注解 Spring AOP详解 PointCut 上面代码存在一个问题, 就是对于excution(* com.example.demo.controller.*.*(..))的大量重…...

Spring-依赖注入的处理过程
前置知识 1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory 注入处理 我们可以看到接口AutowireCapableBeanFactory中有两个方法。 第一个是单个注入: Null…...
2.用python爬取的保存在text文件中的格式为MP4的视频url
文章目录 一、url的保存格式二、MP4视频获取 一、url的保存格式 爬取的视频名字和url保存在text文件中,每一个视频都是一个单独的text,其中text的文件名就是视频的名字,text内容是视频的下载url,并且所有的text都保存在同一个文件…...

Java基于B/S医院绩效考核管理平台系统源码java+springboot+MySQL医院智慧绩效管理系统源码
Java基于B/S医院绩效考核管理平台系统源码javaspringbootMySQL医院智慧绩效管理系统源码 医院绩效考核系统是一个关键的管理工具,旨在评估和优化医院内部各部门、科室和员工的绩效。一个有效的绩效考核系统不仅能帮助医院实现其战略目标,还能提升医疗服…...

UE 蓝图堆栈调试
蓝图打断点后如果想查看断点前的执行逻辑,Tools→Debug→BlueprintDebugger 然后打断点运行,执行顺序是从下往上...

UE4_摄像机_使用摄像机的技巧
学习笔记,不喜勿喷!祝愿生活越来越好! 知识点: a.相机跟随。 b.相机抖动。 c.摄像机移动 d.四元数插值(保证正确旋转方向)。 e.相机注视跟踪。 1、新建关卡序列,并给小车添加动画。 2、创…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...