}
companion object {
private lateinit var sInstance: StockLiveData
@MainThread
fun get(symbol: String): StockLiveData {
sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
return sInstance
}
}
}
- 观察
StockLiveData
StockLiveData.get(symbol).observe(viewLifecycleOwner, Observer { price: BigDecimal? ->
// Update the UI.
})
转换LiveData
Lifecycle
软件包会提供Transformations
类,可以根据另一个实例的值返回不同的LiveData
实例,在将 LiveData 对象分派给观察者之前对存储在其中的值进行更改
map()
用于将实际包含数据的LiveData
和仅用于观察数据的LiveData
进行转换
//User.kt
data class User(var firstName: String, var lastName: String, var age: Int)
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _userLiveData = MutableLiveData()
val userName: LiveData = Transformations.map(_userLiveData) { user ->
“${user.firstName} ${user.lastName}”
}
fun updateTaps() {
_userLiveData.postValue(User(“aa”, “bb”, 12))
}
}
switchMap()
对存储在LiveData
对象中的值应用函数
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _userIdLiveData = MutableLiveData()
val user: LiveData = Transformations.switchMap(_userIdLiveData) { userId ->
Repository.getUse
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
r(userId)
}
fun updateTaps() {
_userIdLiveData.postValue(“cc”)
}
}
// 测试
object Repository {
fun getUser(userId: String): LiveData {
val liveData = MutableLiveData()
liveData.value = User(userId, userId, 0)
return liveData
}
}
合并多个 LiveData 源
MediatorLiveData
允许合并多个 LiveData 源,适用于一个观察者,多个被观察者
//HomeViewModel.kt
class HomeViewModel : ViewModel() {
private val _user1 = MutableLiveData()
private val _user2 = MutableLiveData()
var mediatorLiveData: MediatorLiveData = MediatorLiveData()
init {
mediatorLiveData.addSource(_user1) {
mediatorLiveData.value = it
}
mediatorLiveData.addSource(_user2) {
mediatorLiveData.value = it
}
}
fun updateTaps() {
_user1.postValue(User(“ll”, “nn”, 12))
_user2.postValue(User(“xx”, “bb”, 12))
}
}
// HomeFragment.kt
…
private fun subscribeUI() {
observe(viewModel.mediatorLiveData, ::mediatorLiveDataUpdate)
}
private fun mediatorLiveDataUpdate(user: User?) {
Log.e("==========","$user")
}
相关知识点
知识点一:
postValue
和setValue
setValue
需要运行在主线程,postValue
不用
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread(“setValue”);
mVersion++;
mData = value;
dispatchingValue(null);
}
如果想进阶学习jetpack又缺少学习资料,而我正好薅到这本阿里十年技术专家联合打造“最新”《Jetpack架构组件入门到精通》和《Jetpack强化实战手册》,是你学习Jetpack的葵花宝典。
点击此处蓝字免费获取
1.创建项目
2.沉浸式的布局
3.富文本
4.属性动画
二、Navigation实践之实现APP主框架以及Navigation的相关介绍
1.搭建 Bottom Navigation Activity
2.导航界面跳转
3.Navigation传值
4.Navigation跳转动画
5.导航文件拆分
6.Deeplink导航
三、使用 Coroutines, Retrofit, Moshi实现网络数据请求
1.kotlin - Coroutine 协程
2.用协程和Retrofit实现网络请求
四、使用 TabLayout,ViewPager2 ,RecyclerView实现实现歌单广场页面
1.ViewPager2
2.TabLayout
3.RecyclerView
4.网络数据请求和数据填充
5.优化界面
五、歌单页面MVVM架构改造及其ViewModel和LiveData的使用介绍
1.MVC和MVVM介绍
2.修改歌单页面
1.Paging的优势
2.Paging实现分页加载更多
3.Paging和SwipRefreshLayout组合实现下拉刷新
4.给RecyclerView添加加载状态的Footer
5.发生网络错误后重试
6.帧动画
七、vlayout嵌套横向RecyclerView和Banner 实现主页的展示,自定义Moshi的JsonAdapter
1.vlayout架构分析
2.vlayout布局介绍
3.基础工作准备
4.vlayout实现轮播图
5.字段内容类型不一致
1.添加Room依赖
2.Room详细介绍
3.DataBase创建时插入数据
4.Room实现歌单标签编辑界面的增删改查
1.新建 Entity
2.新建 Dao
3.修改 Database
4.修改 HomeViewModel
5.Migration
1.ExoPlayer介绍
2.ExoPlayer简单的使用方法
3.ExoPlayer简单自定义
4.ExoPlayer高级自定义
5.ExoPlayer在RecyclerView中的复用
1.MotionLayout基础
2.关键帧 Keyframes
3.代码启动动画和监听动画
4.MotionLayout案例分析
1.Flow 引入的场景
2.Flow 的特性
3.Flow的构造函数
4.Flow中间运算函数