Android 架构组件之ViewModel && LiveDa

2020-12-29  本文已影响0人  西塔西塔

什么是ViewModel

首先明确一点,这里讲的ViewModel并不是MVVM架构中所指的VM。这里的ViewModel是架构组件。
ViewModel旨在以注重生命周期的方式存储和管理界面相关的数据,让数据可在发生屏幕旋转等配置更改后继续存在。

什么是LiveData

LiveData是一种可观察的数据存储器类。LiveData 具有生命周期感知能力,遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

为什么用ViewModel && LiveData

使用这两个组件ViewModel && Livedata 我们可以轻松实现MVVM。一般来讲ViewModel会配合LiveData使用,LiveData初始化在ViewModel中。使用这种方式,更符合数据驱动界面的思想。

如何使用

build.gradle依赖

dependencies {
...
def lifecycle_version = "2.2.0"

// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
}

MainModel

class MainModel : ViewModel() {
//初始化LiveData,观察的数据类型即泛型String类型
val contentLiveData: MutableLiveData<String> by lazy {
    MutableLiveData<String>()
}
}

MainActivity

class MainActivity : AppCompatActivity() {
    private lateinit var model: MainModel
    private var i = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        //创建ViewModel
        model = ViewModelProvider(this).get(MainModel::class.java)

        //回调方法中更新ui
        val contentObserver = Observer<String> { content ->
            tvContent.text = content
        }

        //订阅
        model.contentLiveData.observe(this, contentObserver)

        //按钮 模拟更新数据操作
        btContent.setOnClickListener {
            i++
            //通过LiveData.setValue()方法通知数据更新,稍后回调Observer接口方法更新ui
            model.contentLiveData.value = "content+$i"
        }
    }
}

ViewModel用于Activity内多个fragment数据共享

FragmentModel

class FragmentModel : ViewModel() {
    val fragmentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}

FirstFragment

class FirstFragment : Fragment() {
    private lateinit var model: FragmentModel
    private var i = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        model = ViewModelProvider(this).get(FragmentModel::class.java)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        btFirst.setOnClickListener {
            i++
            model.fragmentLiveData.value = "content+$i"
        }
    }
}

SecondFragment

class SecondFragment : Fragment() {
    private lateinit var model: FragmentModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        model = ViewModelProvider(this).get(FragmentModel::class.java)

        model.fragmentLiveData.observe(this, Observer { content ->
            tvSecond.text = content
        })
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}

实际上:同Activity下Fragment获取到的ViewModel实例是同一个,相较于接口回调更简洁。

关于配合协程使用记录一下

ViewModel配合协程使用

class MainModel : ViewModel() {
    val contentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    init {
        viewModelScope.launch {
            val deferred = async(Dispatchers.IO){
                "result"
            }
            val result = deferred.await()

            contentLiveData.value = result
        }
    }
}

Lifecycle配合协程使用

class FirstFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {

        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读