拥抱Jetpack之ViewModel与LiveData搭配使用

1.学会了LiveData可以干什么?

答:可以得到一个可观察并具有生命周期感知能力,存储任何数据类型的封装容器。还可以利用LiveData的特性,自己写一个简单的事件总线,类似于EventBus。

2.LiveData的官方介绍:

LiveData 是一种具有生命周期感知能力、可观察的数据存储器类。

LiveData 的部分特性如下:

  • LiveData 可存储数据;LiveData 是一种可与任何类型数据搭配使用的封装容器。
  • LiveData 是可观察的,这意味着当 LiveData 对象存储的数据发生更改时,观察器会收到通知。
  • LiveData 具有生命周期感知能力。当您将观察器附加到 LiveData 后,观察器就会与 LifecycleOwner(通常是 activity 或 fragment)相关联。LiveData 仅更新处于活跃生命周期状态(例如 STARTED 或 RESUMED)的观察器。您可以在此处详细了解 LiveData 和观察。
3.ViewModel的官方介绍:

ViewModel 类是一种业务逻辑或屏幕级状态容器。它用于将状态公开给界面,以及封装相关的业务逻辑。 它的主要优点是,它可以缓存状态,并可在配置更改后持久保留相应状态。这意味着在 activity 之间导航时或进行配置更改后(例如旋转屏幕时),界面将无需重新提取数据。

ViewModel 的优势

ViewModel 的替代方案是保存要在界面中显示的数据的普通类。在 activity 或 Navigation 目的地之间导航时,这可能会造成问题。此时,如果您不利用保存实例状态机制存储相应数据,系统便会销毁相应数据。ViewModel 提供了一个便捷的数据持久性 API,可以解决此问题。

ViewModel 类的主要优势实际上有两个方面:

  • 它允许您持久保留界面状态。
  • 它可以提供对业务逻辑的访问权限。

持久性

ViewModel 允许数据在 ViewModel 保有的状态和 ViewModel 触发的操作结束后持久存在。这种缓存意味着在常见的配置更改(例如屏幕旋转)完成后,您无需重新提取数据。

作用域

实例化 ViewModel 时,您会向其传递实现 ViewModelStoreOwner 接口的对象。它可能是 Navigation 目的地、Navigation 图表、activity、fragment 或实现接口的任何其他类型。然后,ViewModel 的作用域将限定为 ViewModelStoreOwner 的 Lifecycle。它会一直保留在内存中,直到其 ViewModelStoreOwner 永久消失。

有一系列类是 ViewModelStoreOwner 接口的直接或间接子类。直接子类为 ComponentActivityFragment 和 NavBackStackEntry。如需查看间接子类的完整列表,请参阅 ViewModelStoreOwner 参考文档

当 ViewModel 的作用域 fragment 或 activity 被销毁时,异步工作会在作用域限定到该 fragment 或 activity 的 ViewModel 中继续进行。这是持久性的关键。

如需了解详情,请参阅下文有关 ViewModel 生命周期的部分。

好了,前面都是概念性的东西,下面我们进入实战,手写一个在ViewModel中搭配LiveData的使用Demo。(请允许我全程使用Kotlin来写,对于还在对Kotlin抱以观望的童鞋致歉,哈哈哈~)

4.创建Application,因为本次我们继承的是AndroidViewModel,并且是直接在Application中初始化的(Ps:MyApplication记得在AndroidManifest.xml中引用哦)
package com.xcy.myjetpackdemo

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

class AppViewModel(application: Application) : AndroidViewModel(application) {

    private var _titleLiveData : MutableLiveData<String> = MutableLiveData()
    val titleLiveData : LiveData<String> = _titleLiveData

    fun setTitle(title : String){
        _titleLiveData.postValue(title)
    }
}
package com.xcy.myjetpackdemo

import android.app.Application
import androidx.lifecycle.ViewModelProvider


class MyApplication : Application() {

    companion object{
        lateinit var appViewModel : AppViewModel
    }

    override fun onCreate() {
        super.onCreate()
        //创建ViewModel
        appViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(this).create(AppViewModel::class.java)
    }
}
5.然后在MainActivity中往ViewModel中LiveData存值,并跳转到OtherActivity.kt
package com.xcy.myjetpackdemo

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.activity.viewModels

class MainActivity : AppCompatActivity() {

    private lateinit var mEtInput : EditText
    private lateinit var mBtn : Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mEtInput = findViewById(R.id.et_input_main)
        mBtn = findViewById(R.id.btn_main)

        mBtn.setOnClickListener {
            var inputValue = mEtInput.text.trim().toString()
            if (!inputValue.isNullOrEmpty()){
                //存值
                MyApplication.appViewModel.setTitle(inputValue)

                //跳转到OtherActivity查看存值情况
                var intent = Intent(this@MainActivity,OtherActivity::class.java)
                startActivity(intent)
            }
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/et_input_main"
        android:hint="Please input Value."
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_main"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_input_main"
        android:layout_width="wrap_content"
        android:text="提交"
        android:layout_height="wrap_content"/>

</androidx.constraintlayout.widget.ConstraintLayout>
6.查看ViewModel里LiveData存的值
package com.xcy.myjetpackdemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView

/**
 * 接收值的Activity
 */
class OtherActivity : AppCompatActivity() {

    private lateinit var tvTitle : TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_other)

        tvTitle = findViewById(R.id.tv_title)

        //监听titleLiveData里面值的变化
        MyApplication.appViewModel.titleLiveData.observe(this) {
            tvTitle.text = it
        }
    }
}

activity_other.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".OtherActivity">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="20sp"
        tools:text="Hello" />

</androidx.constraintlayout.widget.ConstraintLayout>
7.运行效果展示

完结撒❀~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐小歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值