Fragment之间进行通信的最佳实现方式

前言

在Android应用程序中,片段(Fragments)是一种组件,用于构建灵活且可重用的用户界面。然而,当在应用程序中使用多个片段时,它们之间的通信变得非常重要。本文将介绍在Android应用程序中实现片段之间和片段与宿主活动之间通信的方式

使用ViewModel进行通信

ViewModel是一种Android架构组件,用于在活动(Activity)和片段之间共享和管理数据。它提供了一种有效的方式,可以将数据存储在内存中,以便在配置更改(如屏幕旋转)或片段之间的切换时保持数据的一致性。

使用ViewModel可以方便地在多个片段之间共享数据,也可以在片段和它们的宿主活动之间共享数据。下面是一个示例,展示了如何使用ViewModel在片段和宿主活动之间共享数据:

// ViewModel
class MainViewModel : ViewModel() {private val mutableSelectedItem = MutableLiveData<Item>()val selectedItem: LiveData<Item> get() = mutableSelectedItemfun selectItem(item: Item) {mutableSelectedItem.value = item}
}// 宿主活动
class MainActivity : AppCompatActivity() {private val viewModel: MainViewModel by viewModels()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)viewModel.selectedItem.observe(this, Observer { item ->// 执行操作})}
}// 片段
class MainFragment : Fragment() {private val viewModel: MainViewModel by activityViewModels()// 当项目被点击时调用fun onItemClicked(item: Item) {// 设置一个新的项目viewModel.selectItem(item)}
}

在这个示例中,宿主活动和片段都可以通过ViewModel来共享和观察数据。它们使用by viewModels()by activityViewModels()来获取ViewModel实例,确保它们使用的是相同的ViewModel对象。

在片段之间共享数据

当在同一个活动中使用多个片段时,这些片段之间通常需要进行通信。为了实现片段之间的通信,可以使用宿主活动作为ViewModel的范围,让这些片段共享同一个ViewModel实例。下面是一个示例,展示了如何使用共享ViewModel在两个片段之间进行通信:

// ViewModel
class MainViewModel : ViewModel() {val filters = MutableLiveData<Set<Filter>>()// ...其他逻辑...
}// 片段 A
class ListFragment : Fragment() {private val viewModel: MainViewModel by activityViewModels()override fun onViewCreated(view: View, savedInstanceState: Bundle?) {viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->// 执行操作})}
}// 片段 B
class FilterFragment : Fragment() {private val viewModel: MainViewModel by activityViewModels()override fun onViewCreated(view: View, savedInstanceState: Bundle?) {viewModel.filters.observe(viewLifecycleOwner, Observer { set ->// 更新选定的过滤器UI})}fun onFilterSelected(filter: Filter) = viewModel.addFilter(filter)fun onFilterDeselected(filter: Filter) = viewModel.removeFilter(filter)
}

在这个示例中,片段A和片段B都使用宿主活动作为ViewModel的范围。它们通过获取相同的ViewModel实例来实现数据的共享和通信。

在父子片段之间共享数据

当使用子片段时,父片段和其子片段可能需要共享数据。为了在父子片段之间共享数据,可以使用父片段作为ViewModel的范围。下面是一个示例,展示了如何在父片段和子片段之间共享数据:

// 父片段
class ListFragment : Fragment() {private val viewModel: MainViewModel by viewModels()override fun onViewCreated(view: View, savedInstanceState: Bundle?) {viewModel.filteredList.observe(viewLifecycleowner, Observer { list ->// 更新列表UI})}
}// 子片段
class ChildFragment : Fragment() {private val viewModel: MainViewModel by viewModels({ requireParentFragment() })// ...其他逻辑...
}

在这个示例中,子片段通过by viewModels({ requireParentFragment() })来获取父片段的ViewModel实例。这样,父子片段之间就可以共享并观察同一个ViewModel中的数据。

使用导航图对ViewModel进行作用域限定

如果你正在使用导航库(Navigation library),你还可以将ViewModel限定在目标NavBackStackEntry的生命周期范围内。例如,可以将ViewModel的作用域限定在ListFragment的NavBackStackEntry上,如下所示:

// ListFragment
class ListFragment : Fragment() {private val viewModel: ListViewModel by navGraphViewModels(R.id.list_fragment)override fun onViewCreated(view: View, savedInstanceState: Bundle?) {viewModel.filteredList.observe(viewLifecycleOwner, Observer { item ->// 更新列表UI})}
}

在这个示例中,通过使用navGraphViewModels()从fragment-ktx库中检索ViewModel,将ViewModel的作用域限定在ListFragment的NavBackStackEntry上。这样,ViewModel的生命周期将与ListFragment的导航生命周期保持一致。

使用Fragment Result API进行通信

在Fragment 1.3.0及更高版本中,每个FragmentManager都实现了FragmentResultOwner接口。这意味着FragmentManager可以作为一个中央存储器来存储片段结果。这种改变使得组件可以通过设置片段结果和监听这些结果来相互通信,而无需这些组件直接引用对方。

要将数据传递回片段A,首先在接收结果的片段A上设置一个结果监听器。在片段A的FragmentManager上调用setFragmentResultListener()方法即可。

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// Use the Kotlin extension in the fragment-ktx artifact.setFragmentResultListener("requestKey") { requestKey, bundle ->// We use a String here, but any type that can be put in a Bundle is supported.val result = bundle.getString("bundleKey")// Do something with the result.}
}button.setOnClickListener {val result = "result"// Use the Kotlin extension in the fragment-ktx artifact.setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}

接收结果:

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)supportFragmentManager.setFragmentResultListener("requestKey", this) { requestKey, bundle ->// We use a String here, but any type that can be put in a Bundle is supported.val result = bundle.getString("bundleKey")// Do something with the result.}}
}

以上是在Android应用程序中实现片段之间和片段与宿主活动之间通信的方式。根据具体的使用场景,可以选择使用ViewModel进行通信,或者使用Fragment Result API进行通信。这些方法都提供了灵活且可靠的方式来实现片段之间的通信,使得Android应用程序的开发更加高效和可维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/92721.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Polygon Miden:扩展以太坊功能集的ZK-optimized rollup

1. 引言 Polygon Miden定位为zkVM&#xff0c;定于2023年Q4上公开测试网。 zk、zkVM、zkEVM及其未来中指出&#xff0c;当前主要有3种类型的zkVM&#xff0c;括号内为其相应的指令集&#xff1a; mainstream&#xff08;WASM, RISC-V&#xff09;EVM&#xff08;EVM bytecod…

Java:正则表达式的命名捕获组

命名捕获组格式 (?<year>.*)-(?<month>.*)-(?<date>.*)完整示例 package com.example.demo;import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexTests {public static void main(String[] args) {String text "2…

3.css的各种选择器

元素选择器 body中的形式 <span class"cls" id"time">2023年03月02日 21:50</span> <span class"cls">央视网</span>head中的形式 <style>h1 {color: #4D4F53;}/* 元素选择器 */span {color: red;} }</styl…

Kubernetes 学习总结(38)—— Kubernetes 与云原生的联系

一、什么是云原生&#xff1f; 伴随着云计算的浪潮&#xff0c;云原生概念也应运而生&#xff0c;而且火得一塌糊涂&#xff0c;大家经常说云原生&#xff0c;却很少有人告诉你到底什么是云原生&#xff0c;云原生可以理解为“云”“原生”&#xff0c;Cloud 可以理解为应用程…

C++:stl:list的常用接口及其模拟实现

本文主要介绍c&#xff1a;stl中list常用接口的功能及使用方法&#xff0c;比较list与vector的区别&#xff0c;并对list的常用接口进行模拟实现。 目录 一、list的介绍和使用 1.list介绍 2.list使用 1.list的构造 2.list iterator的使用 3.list 容量相关 4.list元素访…

[NOIP2011 提高组] 选择客栈

[NOIP2011 提高组] 选择客栈 题目描述 丽江河边有 n n n 家很有特色的客栈&#xff0c;客栈按照其位置顺序从 1 1 1 到 n n n 编号。每家客栈都按照某一种色调进行装饰&#xff08;总共 k k k 种&#xff0c;用整数 0 ∼ k − 1 0 \sim k-1 0∼k−1 表示&#xff09;&am…

机器学习——seaborn实用画图方法简介

0、seaborn简介: 前言:下面的总结只是介绍seaborn有哪些方法和属性,至于具体使用,通过下面给出的名称稍作查找即可。重点应该关注本文介绍的seaborn的使用方法seaborn与机器学习的关系: 知识图谱 0.1、了解即可的知识: seaborn:在matplotlib的基础上画一些更好看的图,在…

Mysql集群高可用架构MHA

Mysql集群高可用架构MHA 一、MHA概述1.1、 MHA 是什么1.2、 MHA 的组成1.3、 MHA 的特点 二、MHA高可用实例2.1、配置主从复制2.1、 安装 MHA 软件2.2、故障模拟2.3、故障修复 一、MHA概述 1.1、 MHA 是什么 MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的M…

计算机毕设 大数据全国疫情数据分析与3D可视化 - python 大数据

文章目录 0 前言1 课题背景2 实现效果3 设计原理4 部分代码5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的…

【C++刷题笔记】螺旋矩阵的两种写法

螺旋矩阵有两种判断大循环结束的方式&#xff0c;第一种是判断需要循环多少次&#xff0c;奇数的话需要额外处理&#xff1b;第二种通过取多少个数判断&#xff0c;不需要额外处理 方法一&#xff1a; class Solution { public:vector<int> spiralOrder(vector<vect…

OpenCV之直线曲线拟合

直线拟合fitLine void fitLine( InputArray points, OutputArray line, int distType,double param, double reps, double aeps ); points:二维点的数组或vector line:输出直线,Vec4f (2d)或Vec6f (3d)的vector distType:距离类型 param:距离参数 reps:径向的精度参数 a…

【2023集创赛】加速科技杯三等奖作品:私密性高精度刷手身份认证系统

本文为2023年第七届全国大学生集成电路创新创业大赛&#xff08;“集创赛”&#xff09;加速科技杯三等奖作品分享&#xff0c;参加极术社区的【有奖征集】分享你的2023集创赛作品&#xff0c;秀出作品风采&#xff0c;分享2023集创赛作品扩大影响力&#xff0c;更有丰富电子礼…

Centos7 安装mysql 5.7

Centos7 安装mysql 5.7 准备工作 centos7 服务器 xshell 安装教程 安装并配置 在安装MySQL之前&#xff0c;我们应该确保系统已经更新到最新的软件包和安全补丁。打开终端&#xff0c;输入以下命令来更新系统 yum update为了方便安装MySQL&#xff0c;我们需要下载并安装…

【数据结构】排序之插入排序和选择排序

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、排序的概念及其分类 &#x1f4d2;1.1排序的概念 &#x1f4d2;1.2排序…

HTML详细基础(二)文件路径

目录 一.相对路径 二.绝对路径 三.超链接标签 四.锚点链接 首先&#xff0c;扩展一些HTML执行的原理&#xff1a; htmL(hypertext markup Language) 是一种规范&#xff08;或者说是一种标准&#xff09;&#xff0c;它通过标记符&#xff08;tag&#xff09;来标记要显示…

【FreeRTOS】FreeRTOS移植stm32详细步骤介绍

我在查找FreeRTOS移植的相关教程特别少&#xff0c;所以想非常详细的介绍FreeRTOS移植stm32详细步骤&#xff0c;包括源码的下载&#xff0c;源码介绍&#xff0c;系统移植&#xff0c;代码验证等&#xff0c;每一步都有对应的介绍和解释&#xff0c;希望可以帮助到你们。 文章…

openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86

文章目录 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x8684.1 BIOS84.2 操作系统环境设置84.3 网络 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x86 …

使用van-dialog二次封装微信小程序模态框

由于微信小程序的wx.showModal不支持富文本内容&#xff0c;无法实现更灵活的展示效果&#xff0c;故需要进行二次封装 实现思路&#xff1a;使用van-dialog以及微信小程序的rich-text实现 代码如下&#xff1a; // index.wxml <van-dialoguse-slottitle"提示"s…

基于vue+Element Table Popover 弹出框内置表格的封装

文章目录 项目场景&#xff1a;实现效果认识组件代码效果分析 封装&#xff1a;代码封装思路页面中使用 项目场景&#xff1a; 在选择数据的时候需要在已选择的数据中对比选择&#xff0c;具体就是点击一个按钮&#xff0c;弹出一个小的弹出框&#xff0c;但不像对话框那样还需…

[DS资源推荐] Data Structure 严书配套代码

下图引入自康建伟老师博客 Github地址 使用说明&#xff1a;康老师博客 使用感受&#xff1a;Orz&#xff01;非常非常非常全面&#xff01;终于能看得下去严书了…