在 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之间相互传数据、共享数据的更多相关文章

  1. 用Broadcast广播在activity之间、fragment之间、activity和fragment之间相互传数据

    例如:A界面要收到B界面的更变信息 一.A界面注册广播 private static final String INTENT_BROADCAST = "android.intent.acti ...

  2. Linux的rsync 配置,用于服务器之间远程传大量的数据

    [教程主题]:rsync [课程录制]: 创E [主要内容] [1] rsync介绍 Rsync(Remote Synchronize) 是一个远程资料同步工具,可通过LAN/WAN快速同步多台主机, ...

  3. Navigation 实现不同fragment之间的view的共享(含动画过渡)

    以imageView的共享举例 两个fragment都要有各自的imageview视图,id可以不同,但transitonName一定要相同, 都要指定相同的src 例如: fragment A &l ...

  4. iOS应用程序间共享数据

    我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来 ...

  5. fragment之间的信息交互——onActivityResult()不经过Activity

    1.本文讲述如何fragment与fragment之间互传信息,不用使用Activity的onActivityResult()方法 核心思想:FirstFragment获取到SecondFragmen ...

  6. 用PSCP在Windows和Linux之间相互传输文件

    在Linux服务器之间相互传文件我们常用 scp命令,但是在Linux和Windows之间相互传输就不那么直接了. 使用 Putty的 PSCP 则会简单的多 1. 下载 http://www.chi ...

  7. Android Fragment之间的通信(用fragment替换掉XML布局文件中的一个线性布局)

    1.XML布局 (1)主界面 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xml ...

  8. Android应用程序组件Content Provider在应用程序之间共享数据的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...

  9. 多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)

    ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,Threa ...

随机推荐

  1. 17. Vue2.4+新增属性$listeners

    现在我们来讨论一种情况,A组件与C组件怎么通信,我们有多少种解决方案? 我们使用VueX来进行数据管理,但是如果项目中多个组件共享状态比较少,项目比较小,并且全局状态比较少,那使用VueX来实现该功能 ...

  2. Day06_27_多态

    多态 最关键一句话: 父类引用 指向(=) 子类对象 Animal a = new Cat(); 什么是多态? 官方说: 接口的多种不同的实现方式即为多态. 多态性是允许你将父对象设置成为一个或更多的 ...

  3. MySQL数据库干货分享!unsigned使用案例分析

    今天主要写一下unsigned的使用,进入正文前先分享一套博主觉得讲的很详细很实用的MySQL教程给大家 https://www.bilibili.com/video/BV1fx411X7BD 好了, ...

  4. 11- client测试

    client是客户端,软件分为客户端与服务端,客户端就是我们使用的软件,比如浏览器,QQ,抖音等.服务端就是客户端使用操作,服务端给你响应的请求.

  5. Ribbon、Feign和OpenFeign的区别

    Spring Cloud 微服务架构学习记录与示例 Ribbon Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件 Ribbon 可以用来做客户端负载均衡,调用注册中心的服 ...

  6. hdu4907 水dp 或者set

    题意:       给你一些被占用的时间点,然后有一些询问,每次输出大于等于询问时间的没被占用的最小的那个时间. 思路:       直接把所有用过的时间标记上,然后倒着更新一遍当前最小空余时间,或者 ...

  7. php、jsp、asp和aspx的区别

    目录 PHP JSP ASP ASP.NET PHP PHP是一种跨平台的服务器端的嵌入式脚本语言.它大量地借用C.Java 和 Perl 语言的语法,并耦合PHP自己的特性,使WEB开发者能够快速地 ...

  8. ajax提交session超时跳转页面使用全局的方法来处理

    来自:http://www.jb51.net/article/43770.htm 如果是ajax提交,超时时从服务器发出的跳转命令就不会起作用,所以如果是session超时,而且是在ajax请求,就在 ...

  9. Maven关于web.xml中Servlet和Servlet映射的问题

    在配置Servlet时,有两个地方需要配置. 一个是<servlet>,另一个是<servlet-Mapping>,这两个一个是配置Servlet,一个是配置其映射信息. &l ...

  10. 一款好用的数据血缘关系在线工具--SQLFlow

      l  数据血缘关系(data lineage) 数据血缘属于数据治理中的一个概念,是在数据溯源的过程中找到相关数据之间的联系,它是一个逻辑概念.数据治理中经常提到血缘分析,血缘分析是保证数据融合的 ...