【奇技淫巧】巧用 kotlin 扩展函数和 typealias 封装 带网络状态和解决「粘性」事件的 LiveData

2020-06-05 00:00:00 函数 可以使用 扩展 封装 希望

关于 LiveData 两个常用的姿势

使用包装类传递事件

我们在使用 LiveData 时可能会遇到「粘性」事件的问题,该问题可以使用包装类的方式解决。解决方案见 [译] 在 SnackBar,Navigation 和其他事件中使用 LiveData(SingleLiveEvent 案例)

使用时是这样的

class ListViewModel : ViewModel {
    private val _navigateToDetails = MutableLiveData<Event<String>>()

    val navigateToDetails : LiveData<Event<String>>
        get() = _navigateToDetails


    fun userClicksOnButton(itemId: String) {
        _navigateToDetails.value = Event(itemId)  // Trigger the event by setting a new Event as a new value
    }
}

myViewModel.navigateToDetails.observe(this, Observer {
    it.getContentIfNotHandled()?.let { // Only proceed if the event has never been handled
        startActivity(DetailsActivity...)
    }
})
复制代码

不过这样写甚是繁琐,我们可以使用更优雅的方式解决该问题

//为 LiveData<Event<T>>提供类型别名,使用 EventLiveData<T> 即可
typealias EventMutableLiveData<T> = MutableLiveData<Event<T>>

typealias EventLiveData<T> = LiveData<Event<T>>
复制代码

使用 typealias 关键字,我们可以提供一个类型别名,可以这样使用

//等价于 MutableLiveData<Event<Boolean>>(Event(false))
val eventContent = EventMutableLiveData<Boolean>(Event(false))
复制代码

现在声明时不用多加一层泛型了,那么使用时还是很繁琐

我们可以借助 kotlin 的 扩展函数更优雅的使用

event 扩展函数
使用

demo 中封装了两种形式的 LiveData,一种为 LiveData<Boolean>,一种为 EventLiveData<Boolean>,当屏幕旋转时,前者会再次回调结果,而后者由于事件已被处理而不执行 onChanged,我们通过 Toast 可观察到这一现象

java 版的可参考

封装带网络状态的数据

很多时候我们在获取网络数据时要封装一层网络状态,例如:加载中,成功,失败

在使用时我们遇到了和上面一样的问题,多层泛型用起来很麻烦

我们依然可以使用 typealias + 扩展函数来优雅的处理该问题

typealias
扩展函数
使用

demo 截图

demo

Demo

demo 在这

往期文章

该系列主要介绍一些「骚操作」,它未必适合生产环境使用,但是是一些比较新颖的思路

  • 【奇技淫巧】AndroidStudio Nexus3.x搭建Maven私服遇到问题及解决方案

  • 【奇技淫巧】什么?项目里gradle代码超过200行了!你可能需要 Kotlin+buildSrc Plugin

  • 【奇技淫巧】gradle依赖查找太麻烦?这个插件可能帮到你

  • 【奇技淫巧】Android组件化不使用 Router 如何实现组件间 activity 跳转

  • 【奇技淫巧】新的图片加载库?基于Kotlin协程的图片加载库——Coil

  • 【奇技淫巧】使用 Navigation + Dynamic Feature Module 实现模块化

  • 【奇技淫巧】除了 buildSrc 还能这样统一配置依赖版本?巧用 includeBuild

我的其他系列文章 在这里

关于我

我是 Fly_with24

  • 掘金

  • 简书

  • Github

相关文章