引入依赖
app/build.gradle
buildFeatures {
dataBinding = true
}
// liveData
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
// viewModel
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
// koin
implementation 'org.koin:koin-android:2.0.1'
implementation 'org.koin:koin-androidx-scope:2.0.1'
implementation 'org.koin:koin-androidx-viewmodel:2.0.1'
自定义ViewModel
LiveData本身没有提供公共方法更新值。如果需要修改LiveData的数据的话,可以通过MutableLiveData来暴露共有方法setValue()和postValue()。通常在在ViewModel中使用MutableLiveData,而MutableLiveData暴露不可变的LiveData给Observer。与Observer建立关系后,通过修改LiveData的值从而更新Observer中的视图。
LiveData使用总结
- 永远只暴按个露永远不可变得LiveData给外部。这样在非ViewModel中就只能观察LiveData得数据变化,而不能给LiveDada设置数据。
package com.wanandroid.ui.first
import androidx.databinding.BaseObservable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
/**
* Created by Donkey
* on 2020/8/8
*/
class ArticleViewModel: ViewModel() {
private var _uiState = MutableLiveData<Int>()
init {
_uiState.value = 10
}
val uiState: LiveData<Int>
get() = _uiState
fun plusOne() {
val count = _uiState.value?:0
_uiState.value = count + 1
}
}
定义Koin module
package com.wanandroid
import com.wanandroid.ui.first.ArticleViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
/**
* Created by Donkey
* on 2020/8/11
*/
val viewModelModule = module {
viewModel { ArticleViewModel() }
}
val repositoryModule = module {
}
val appModule = listOf(viewModelModule, repositoryModule)
启动 Koin
class App: Application() {
companion object {
var _context: Application? = null
fun getContext(): Context {
return _context!!
}
}
override fun onCreate() {
super.onCreate()
_context = this
startKoin {
modules(appModule)
}
}
}
页面注入依赖
private val articleViewModel by viewModel<ArticleViewModel>() //koin
// 等同于
private val articleViewModel : ArticleViewModel by viewModel() //koin
articleViewModel.uiState.observe(viewLifecycleOwner, Observer { //观察LiveData 的对象
Log.d("uiState", it.toString())
})
完整的代码
BaseVMFragment
package com.wanandroid.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
/**
* Created by Donkey
* on 2020/8/8
*/
abstract class BaseVMFragment<T:ViewDataBinding>(@LayoutRes val layoutId: Int) : Fragment(layoutId) {
lateinit var binding: T
protected fun <T : ViewDataBinding> binding(
inflater: LayoutInflater,
@LayoutRes layoutId: Int,
container: ViewGroup?
): T = DataBindingUtil.inflate<T>(inflater, layoutId, container, false).apply {
lifecycleOwner = this@BaseVMFragment
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = binding(inflater, layoutId, container)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.lifecycleOwner = this
startObserve()
initView()
initData()
super.onViewCreated(view, savedInstanceState)
}
abstract fun initView()
abstract fun initData()
abstract fun startObserve()
}
FirstFragment
package com.wanandroid.ui.first
import android.util.Log
import androidx.lifecycle.Observer
import com.wanandroid.R
import com.wanandroid.base.BaseVMFragment
import com.wanandroid.databinding.FragmentFirstBinding
import org.koin.androidx.viewmodel.ext.android.viewModel
/**
* Created by Donkey
* on 3:18 PM
*/
class FirstFragment : BaseVMFragment<FragmentFirstBinding>(R.layout.fragment_first) {
private val articleViewModel : ArticleViewModel by viewModel() //koin
override fun initView() {
binding.run {
viewModel = articleViewModel
}
}
override fun initData() {
}
override fun startObserve() {
articleViewModel.uiState.observe(viewLifecycleOwner, Observer {
Log.d("uiState", it.toString())
})
}
}
fragment_first.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.wanandroid.ui.first.ArticleViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/infoText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="@{viewModel.uiState.toString()}"
android:textSize="30sp"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/plusOneBtn"
app:layout_constraintTop_toBottomOf="@+id/infoText"
android:onClick="@{()->viewModel.plusOne()}"
android:text="加一"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>