fragment之间相互传数据、共享数据
在 Fragment 之间共享数据
Activity 中的两个或更多 Fragment 需要相互通信是一种很常见的现象。想象一下拆分视图 (master-detail
) Fragment 的常见情况,假设您有一个 Fragment,在该 Fragment 中,用户从列表中选择一项,还有另一个 Fragment,用于显示选定项的内容。这种情况不太容易处理,因为这两个 Fragment 都需要定义某种接口描述,并且所有者 Activity 必须将两者绑定在一起。此外,这两个 Fragment 都必须处理另一个 Fragment 尚未创建或不可见的情况。
可以使用 ViewModel
对象解决这一常见的难点。这两个 Fragment 可以使用其 Activity 范围共享 ViewModel
来处理此类通信,如以下示例代码所示:
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>() fun select(item: Item) {
selected.value = item
}
} class MasterFragment : Fragment() { private lateinit var itemSelector: Selector // Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
} class DetailFragment : Fragment() { // Use the 'by activityViewModels()' Kotlin property delegate
// from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
// Update the UI
})
}
}
请注意,这两个 Fragment 都会检索包含它们的 Activity。这样,当这两个 Fragment 各自获取 ViewModelProvider
时,它们会收到相同的 SharedViewModel
实例(其范围限定为该 Activity)。
此方法具有以下优势:
- Activity 不需要执行任何操作,也不需要对此通信有任何了解。
- 除了
SharedViewModel
约定之外,Fragment 不需要相互了解。如果其中一个 Fragment 消失,另一个 Fragment 将继续照常工作。 - 每个 Fragment 都有自己的生命周期,而不受另一个 Fragment 的生命周期的影响。如果一个 Fragment 替换另一个 Fragment,界面将继续工作而没有任何问题。
当在其中一个fragment中修改了数据,希望另外一个fragment的数据也可以被修改。使用“共享 view model”的方式避免了一大堆炒鸡繁琐的回调接口。
class DatePickerFragment:DialogFragment() {
private val crimeDetailViewModel:CrimeDetailViewModel by activityViewModels()//1设置为共享viewmodel override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
super.onCreateDialog(savedInstanceState)
val dateListener = DatePickerDialog.OnDateSetListener{
_, year, month, dayOfMonth ->
val chooseDate: Date = GregorianCalendar(year, month, dayOfMonth).time//
val crime = crimeDetailViewModel.crimeLiveData.value
crime?.date = chooseDate
crimeDetailViewModel.saveCrime(crime!!)//2保存
}
val calendar = Calendar.getInstance()
calendar.time = crimeDetailViewModel.crimeLiveData.value?.date ?: Date()//
val initYear = calendar.get(Calendar.YEAR)
val initMonth = calendar.get(Calendar.MONTH)
val initDay = calendar.get(Calendar.DAY_OF_MONTH) return DatePickerDialog(
requireContext(),
dateListener,
initYear,
initMonth,
initDay
)
}
}
上面的代码实例中就使用了共享viewmodel.当然在另一个activity中也是用 by activityViewModels()这种方式初始化。
配合Navigation和livedata使用简直不要太丝滑!!!
fragment之间相互传数据、共享数据的更多相关文章
- 用Broadcast广播在activity之间、fragment之间、activity和fragment之间相互传数据
例如:A界面要收到B界面的更变信息 一.A界面注册广播 private static final String INTENT_BROADCAST = "android.intent.acti ...
- Linux的rsync 配置,用于服务器之间远程传大量的数据
[教程主题]:rsync [课程录制]: 创E [主要内容] [1] rsync介绍 Rsync(Remote Synchronize) 是一个远程资料同步工具,可通过LAN/WAN快速同步多台主机, ...
- Navigation 实现不同fragment之间的view的共享(含动画过渡)
以imageView的共享举例 两个fragment都要有各自的imageview视图,id可以不同,但transitonName一定要相同, 都要指定相同的src 例如: fragment A &l ...
- iOS应用程序间共享数据
我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来 ...
- fragment之间的信息交互——onActivityResult()不经过Activity
1.本文讲述如何fragment与fragment之间互传信息,不用使用Activity的onActivityResult()方法 核心思想:FirstFragment获取到SecondFragmen ...
- 用PSCP在Windows和Linux之间相互传输文件
在Linux服务器之间相互传文件我们常用 scp命令,但是在Linux和Windows之间相互传输就不那么直接了. 使用 Putty的 PSCP 则会简单的多 1. 下载 http://www.chi ...
- Android Fragment之间的通信(用fragment替换掉XML布局文件中的一个线性布局)
1.XML布局 (1)主界面 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xml ...
- Android应用程序组件Content Provider在应用程序之间共享数据的原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...
- 多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,Threa ...
随机推荐
- 9. resultMap 结果映射集
@Data public class CreditCard extends BankCard { /** * 消费额度 */ private String creditLine; } @Data pu ...
- MySQL8安装教程及问题解决
目录 1.下载MySQL的zip文件,解压,在根目录(bin所在的目录)下创建my.ini文件 2.管理员模式打开命令提示符(shell或者说小黑窗),按以下命令操作. 3.不过......我这里密码 ...
- 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别
前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...
- hdu4280 最大流DINIC
题意: x最小的到x最大的点同一时间的最大运输量. 思路: 裸的最大流,不解释,注意一点,记得加上防爆栈. #pragma comment(linker, "/STA ...
- 病毒木马查杀实战第021篇:Ring3层主动防御之编程实现
前言 我们这次会依据上次的内容,编程实现一个Ring3层的简单的主动防御软件.整个程序使用MFC实现,程序开始监控时,会将DLL程序注入到explorer.exe进程中,这样每当有新的进程创建,程序首 ...
- Python中的输入(input)和输出打印
目录 最简单的打印 打印数字 打印字符 字符串的格式化输出 python中让输出不换行 以下的都是在Python3.X环境下的 使用 input 函数接收用户的输入,返回的是 str 字符串 最简单的 ...
- Windows Server中企业证书服务的安装
目录 企业证书服务的安装 证书服务的应用 企业证书服务的安装 企业证书服务是基于域的,所以需要该服务器是域控服务器. 添加角色,勾选 Active Directory 证书服务 然后后面的一直下一步, ...
- idea中修改代码大小设置
修改代码大小 控制台字体大小
- 多线程-2.线程创建方式和Thread类
线程的创建方式 1.继承Thread类,重写run方法,示例如下: 1 class PrimeThread extends Thread { 2 long minPrime; 3 PrimeThrea ...
- springboot 项目中css js 等静态资源无法访问的问题
目录 问题场景 问题分析 问题解决 问题场景 今天在开发一个springboot 项目的时候突然发现 css js 等静态资源竟然都报404找不到,折腾了好久终于把问题都解决了,决定写篇博客,纪录总结 ...