【Jetpack】学穿:ViewModel → 视图模型(中)
设置文本 预留点击接口而已 再接着到列表Fragment的布局 直接一个RecyclerView (fragment_list.xml)
?xml version 1.0 encoding utf-8 ? FrameLayout xmlns:android http://schemas.android.com/apk/res/android android:layout_width 150dp android:layout_height match_parent androidx.recyclerview.widget.RecyclerView android:id id/rv_list android:layout_width match_parent android:layout_height match_parent / /FrameLayout
接着自定义ViewHolder 维护一个选中的值 配置LiveData
class SharedViewModel: ViewModel() { private val mSelectData MutableLiveData String () fun select(data: String) { mSelectData.value data } fun getSelected() mSelectData }
再接着把ListFragment也写出来 获取宿主Activity作用域的SharedViewModel实例 点击时更新值
class ListFragment(data: ArrayList String ): Fragment(R.layout.fragment_list) { private var mData data // 定义SharedViewModel变量 private var mModel: SharedViewModel? null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 获得宿主Activity作用域内的SharedViewModel实例 mModel ViewModelProvider(requireActivity()).get(SharedViewModel::class.java) view.findViewById RecyclerView (R.id.rv_list).apply { adapter ListAdapter(mData).also { it.setOnItemClickListener(object : ListAdapter.ItemClickListener { override fun onItemClick(choose: String) { // 更新ViewModel中的mSelectData mModel?.select(choose) layoutManager LinearLayoutManager(activity) }
在接着到右侧Fragment xml里就一个简单的TextView (fragment_content.xml)
?xml version 1.0 encoding utf-8 ? LinearLayout xmlns:android http://schemas.android.com/apk/res/android android:layout_width match_parent android:layout_height match_parent android:background android:color/holo_blue_light TextView android:id id/tv_content android:layout_width match_parent android:layout_height match_parent android:gravity center / /LinearLayout
补齐ContentFragment
class ContentFragment : Fragment(R.layout.fragment_content) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 获取宿主Activity作用域的SharedViewModel实例 然后监听数据变化 ViewModelProvider(requireActivity()).get(SharedViewModel::class.java).getSelected() .observe(viewLifecycleOwner) { view.findViewById TextView (R.id.tv_content).text 您翻牌了 ${it} }
紧着是测试Activity的xml (activity_vm_test.xml)
?xml version 1.0 encoding utf-8 ? LinearLayout xmlns:android http://schemas.android.com/apk/res/android android:layout_width match_parent android:layout_height match_parent android:orientation horizontal FrameLayout android:id id/fly_choose android:layout_width wrap_content android:layout_height match_parent / FrameLayout android:id id/fly_content android:layout_width 0dp android:layout_height match_parent android:layout_weight 1 / /LinearLayout
最后上测试Activity
class VMTestActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_vm_test) val mData arrayListOf( XX , XX , XX , XX , XXX , XX , XX , XX ) supportFragmentManager.apply { beginTransaction().replace(R.id.fly_choose, ListFragment(mData)).commit() beginTransaction().replace(R.id.fly_content, ContentFragment()).commit() }
别看这里代码好像很多的样子 只是为了便于读者copy运行体验而已 核心就这四点
通过这样的方式 间接实现了跨页面通信 宿主Activity还蒙在鼓里 (无代码入侵) 两个Fragment就偷偷完成了py交易 妙啊
上面两个Fragment轻松实现数据共享的例子 得益于ViewModel的 作用域可控 在创建 ViewModelProvider 时注入不同的 ViewModelStoreOwner 来反映作用域。
如果换成传入 Fragment实例本身 作用域就 仅限于此Fragment 当此Fragment销毁时 对应的ViewModel实例也会被销毁。
看一波源码探探原理 先跟下 ViewModelProvider 的构造方法
初始化了一个Factory和ViewModelStore 先看第一个参数 调用了 owner.getViewModelStore()
此方法返回一个 ViewModelStore 跟下
吼 内部 维护一个ViewModel的集合 还提供一个clear()方法 遍历回调ViewModel的clear()方法 并清空集合。
所以包含关系是 ViewModelProvider → ViewModelStore → ViewModel
接着看第二个参数 根据传入的ViewModelStoreOwner不同 使用不同的工厂实例
Android Jetpack系列之ViewModel ViewModel的定义:**ViewModel旨在以注重生命周期的方式存储和管理界面相关的数据**。ViewModel本质上是视图(View)与数据(Model)之间的桥梁,想想以前的MVC模式,视图和数据都会写在Activity/Fragment中,导致Activity/Fragment过重,后续难以维护,而ViewModel将视图和数据进行了分离解耦,为视图层提供数据。
大放光彩的安卓Jetpack组件-ViewModel(终) 前面我们已经说过Jetpack中ViewModel的作用、用法以及使用要点,但还缺少在Activity中的实例展示,所以本节我们将结合结果展示与代码进行解读,希望能更好的展示出ViewModel的风采。
大放光彩的安卓Jetpack组件-ViewModel(二) 上回我们说到使用方法,但没有具体去说明使用的要点,其实ViewMode还是挺容易上手的,这节我们来具体说明一些使用要点与运用方式。
相关文章
- Android Jetpack组件 Compose 使用介绍
- Android Jetpack组件 DataStore的使用和简单封装
- Android Jetpack架构开发,从入门到实战,看这一篇就够了
- Android Jetpack Compose最全上手指南,你学会了吗?
- Jetpack系列-ViewModel的使用及原理浅析
- 送你一份 Android Jetpack 架构入门秘籍,从入门到强化实战
- Android Jetpack系列--1.Lifecycle使用及源码解析
- Android Jetpack组件之Lifecycles库详解
- Android Jetpack组件 - ViewModel,LiveData使用以及原理
- Android 工程师编写的 SwiftUI 与 Jetpack Compose深度对比
- Jetpack Compose 教程:如何使用 FlowLayout
- 探索 Android Jetpack Compose
- Jetpack Compose 声明式 UI入门简介
- Jetpack Compose教程之 被动视图 让你的 UI 代码简单而愚蠢
- Jetpack Compose教程之 Jetpack Compose 核心功能介绍
- Jetpack Compose教程之 为什么 Jetpack Compose 不像看起来那么容易?
- 超级简洁、彻底组件化的轻量级Android Kotlin Jetpack MVVM组件化框架
- Jetpack Compose之线性布局和帧布局
- Jetpack太香了,让开发效率提升了不少
- 如何在 Jetpack Compose 中调试重组
- 一起看 I/O | Jetpack Compose 中的新特性
- 让你易上手的Jetpack Compose教程:帮你写出漂亮的小组件-Jetpack Glance
- Android Jetpack-ViewModel
- Jetpack Composes 【01】
- Jetpack架构组件(二)Lifecycle使用
- 带你了解Android Jetpack