美文网首页js css html
JetPack<第二篇>:LiveData & ViewMode

JetPack<第二篇>:LiveData & ViewMode

作者: NoBugException | 来源:发表于2022-08-08 09:26 被阅读0次

    LiveData
    1、定义:可观察的数据持有对象
    2、优点:
    (1)自动更新UI
    (2)无内存泄漏
    (3)不会引起程序崩溃
    (4)无需手动处理生命周期
    (5)共享资源 -- 需要继承LiveData并且实现单例
    ViewModel
    1、定义:用来处理跟UI相关的数据的类
    2、优点:
    (1)设备信息发生变更数据不会消失
    (2)同一个Activity之间的Fragment可以实现数据共享 -- 使用Fragment中的activity提供ViewModel

    1、添加依赖

    ext.lifecycleVersion = '2.2.0-alpha01'
    dependencies {
        // liveData
        implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
        // viewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel- ktx:$rootProject.lifecycleVersion"
        implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleVersion"
    }
    

    2、简单实现

    【1】创建ViewModel,并在ViewModel创建MutableLiveData
    
    class UserModel(application: Application) : AndroidViewModel(application) {
    
        val userLiveData = MutableLiveData<User>() // 创建 LiveData 对象
        private var mApplication: Application? = null
    
        init {
            userLiveData.postValue(User("张三", 2)) // 通知数据变化了
            mApplication = application
        }
    
        /**
         * 更新用户信息
         */
        fun updateUserInfo() {
            val user = userLiveData.value?.apply {
                userName = "张三"
                age = (1..100).random()
            }
            userLiveData.value = user // 或改成 userLiveData.postValue(user)
    
        }
    }
    
    【2】User类
    
    data class User(var userName: String, var age: Int)
    
    【3】ViewModelProvider
    
        val userModel = ViewModelProvider(this@LiveDataActivity).get(UserModel::class.java)
    
    【4】使用 observe 或 observeForever 绑定观察者
    
        // 使用 observe 会让观察者随着生命周期的活跃而活跃,当生命周期处于活跃状态时LiveData才会更新数据,反之不会更新数据
        // 不需要主动调用 removeObserver(Observer) 移除观察者
        userModel.userLiveData.observe(this@LiveDataActivity, Observer<User> {
            binding.userinfo.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
        })
    
        // 使用 observeForever,会导致观察者一直处于活跃状态
        // 我们需要主动调用 removeObserver(Observer) 移除观察者
        userModel.userLiveData.observeForever {
            binding.userinfo.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
        }
    
    【5】触发数据变化
    
        binding.activityDataButton.setOnClickListener {
             userModel.updateUserInfo()
        }
    

    3、map 和 switchMap

        // 使用map函数,将User类型转成Int类型,Observer的返回值也从User类型转换成Int类型
        // Function 第一个参数表示输入,第二个参数表示输出
        // map 第一个参数表示输入数据,第二个参数Function的返回值是输出数据
        Transformations.map(userModel.userLiveData, Function<User, Int> {
            it.age
        }).observe(this@LiveDataActivity, Observer<Int> {
            binding.userinfo1.text = "大家好,我今年 $it 岁了!"
        })
    
    
        // 使用switchMap函数,将User类型转成LiveData<Int>类型,Observer的返回值从User类型转换成Int类型
        // Function 第一个参数表示输入,第二个参数表示输出
        // map 第一个参数表示输入数据,第二个参数Function的返回值是输出数据
        Transformations.switchMap(userModel.userLiveData, Function<User, LiveData<Int>> {
            val userLiveData = MutableLiveData<Int>()
            val age = userModel.userLiveData.value?.age
            userLiveData.postValue(age)
            userLiveData
        }).observe(this@LiveDataActivity, Observer<Int> {
            binding.userinfo.text = "大家好,我今年 $it 岁了!"
        })
    
    其它步骤和 【2】 保持一致。
    

    4、使用 MediatorLiveData 统一管理多个LiveData

    【1】创建ViewModel,并在ViewModel创建MediatorLiveData和MutableLiveData
    
    class UserModelByMediator(application: Application) : AndroidViewModel(application) {
    
        var mediatorLiveData: MediatorLiveData<User> = MediatorLiveData() // 创建 LiveData 集合对象,管理多个LiveData
        val userLiveData1 = MutableLiveData<User>() // 创建 LiveData 对象1
        val userLiveData2 = MutableLiveData<User>() // 创建 LiveData 对象2
        private var mApplication: Application? = null
    
        init {
            mediatorLiveData.addSource(userLiveData1) {
                mediatorLiveData.value = it
            }
            mediatorLiveData.addSource(userLiveData2) {
                mediatorLiveData.value = it
            }
            userLiveData1.postValue(User("张三", 2)) // 通知数据变化了
            userLiveData2.postValue(User("李四", 3)) // 通知数据变化了
            mApplication = application
        }
    
        /**
         * 更新用户信息1
         */
        fun updateUserInfo1() {
            val user = userLiveData1.value?.apply {
                userName = "张三"
                age = (1..100).random()
            }
            userLiveData1.value = user // 或改成 userLiveData1.postValue(user)
        }
    
        /**
         * 更新用户信息1
         */
        fun updateUserInfo2() {
            val user = userLiveData2.value?.apply {
                userName = "李四"
                age = (1..100).random()
            }
            userLiveData2.value = user // 或改成 userLiveData2.postValue(user)
        }
    }
    
    【2】user类
    
    和上面一致
    
    【3】ViewModelProvider
    
    val userModelByMediator = ViewModelProvider(this@LiveDataActivity).get(UserModelByMediator::class.java)
    
    【4】绑定观察者
    
        userModelByMediator.mediatorLiveData.observe(this@LiveDataActivity) {
            when(it.userName) {
                "张三" -> binding.userinfo1.text = "大家好,我叫${it.userName},今年${it.age}岁了!"
                "李四" -> binding.userinfo2.text = "大家好,我叫${it.userName},今年${it.age}岁了!"
            }
        }
    
    【5】触发数据变化
    
        binding.activityDataButton.setOnClickListener {
            userModelByMediator.updateUserInfo1()
            userModelByMediator.updateUserInfo2()
        }
    

    5、LiveData的单例实现

    【1】创建一个单例
    
    class UserLiveData : LiveData<User>() {
        companion object {
    
            private lateinit var mInstance: UserLiveData
    
            @JvmStatic
            @MainThread
            fun get(): UserLiveData {
                mInstance = if (::mInstance.isInitialized) {
                    mInstance
                } else {
                    UserLiveData()
                }
                return mInstance
            }
        }
    
        override fun onActive() {
            super.onActive()
        }
    
        override fun onInactive() {
            super.onInactive()
        }
    
        /**
         * 更新数据
         */
        fun updateUserInfo() {
            var user = get().value
            if (user == null) {
                user = User("", 0)
            }
            user.apply {
                userName = "张三"
                age = (1..100).random()
            }
            value = user // 或者 将 value = user 改成 postValue(user)
        }
    }
    
    onActive 和 onInactive 两个方法很重要
    onActive:Activity 激活时执行
    onInactive:Activity 挂起时执行
    
    【2】绑定观察者
    
        // LiveData单例实现方式
        UserLiveData.get().observe(this@LiveDataActivity) {
            binding.userinfo1.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
        }
    
    【3】触发数据更新
    
        binding.activityDataButton.setOnClickListener {
            UserLiveData.get().updateUserInfo()
        }
    

    6、ViewModelProvider.Factory使用

    没有使用 ViewModelProvider.Factory 的代码:
    
    val userModel = ViewModelProvider(this@LiveDataActivity).get(UserModel::class.java)
    
    使用  ViewModelProvider.Factory 的代码:
    
    val userModel = ViewModelProvider(this@LiveDataActivity, UserModelFactory(application)).get(UserModel::class.java)
    
    不使用 ViewModelProvider.Factory 的两种情况:
    【1】当 Model 继承 AndroidViewModel 时,并且 Model 只有 Application 参数时:
    class UserModel(application: Application) : AndroidViewModel(application)
    【2】当 Model 继承 ViewModel,并且 ViewModel 没有参数时:
    class UserModel : ViewModel()
    
    使用 ViewModelProvider.Factory 的情况:
    【1】当 Model 继承 AndroidViewModel 时,并且 Model 有除了 Application 参数之外还有其它参数时:
    class UserModel(application: Application, age: Int) : AndroidViewModel(application)
    
    class UserModelFactory(private val application: Application) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(UserModel::class.java)) {
                return UserModel(application, 3) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
    
    【2】当 Model 继承 ViewModel,并且 Model 有参数时:
    val userModel = ViewModelProvider(this@LiveDataActivity, UserModelFactory(application)).get(UserModel::class.java)
    
    class UserModelFactory(private val application: Application) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(UserModel::class.java)) {
                return UserModel(application) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
    

    [本章完...]

    相关文章

      网友评论

        本文标题:JetPack<第二篇>:LiveData & ViewMode

        本文链接:https://www.haomeiwen.com/subject/tacwwrtx.html