【原创】jetpack-LiveData实现双向绑定
2020-08-17 本文已影响0人
seekting
jetpack-LiveData实现双向绑定
先提一下使用androidx jetpack
gradle 6.1.1
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
classpath
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
app gradle
lintOptions {
checkReleaseBuilds false
abortOnError false
}
buildFeatures {
dataBinding true
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.0"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
}
xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout 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"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/all_activity"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={mDBViewModel.username.firstName}" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={mDBViewModel.username.lastName}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={mDBViewModel.username.fullName}"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={mDBViewModel.pwd}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->mDBViewModel.clickLogin(@string/all_activity)}"
/>
</LinearLayout>
<data>
<variable
name="mUserName"
type="String" />
<variable
name="mDBViewModel"
type="com.seekting.demo2019.jetpack.DBViewModel" />
</data>
</layout>
activity
package com.seekting.demo2019.jetpack
import android.app.Application
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableField
import androidx.lifecycle.*
import com.seekting.common.ToastUtils
import com.seekting.demo2019.DemoGroup
import com.seekting.demo2019.R
import com.seekting.demo2019.databinding.DbActivityBinding
import com.seekting.demo_lib.Demo
class UserName {
var firstName = "zhang"
set(value) {
field = value
setFullNameIn()
}
var lastName = "seekting"
set(value) {
field = value
setFullNameIn()
}
var fullName = ObservableField("")
private fun setFullNameIn() {
fullName.set("$firstName.$lastName")
}
}
class DBViewModel(application: Application) : AndroidViewModel(application) {
var username: MutableLiveData<UserName>? = null
var pwd: String = ""
init {
username = MutableLiveData<UserName>()
username?.postValue(UserName())
pwd = "zxt"
}
private fun checkLogin(): Boolean {
if (TextUtils.equals(username?.value!!.fullName.get(), "zhang.seekting") && TextUtils.equals("zxt", pwd)) {
return true
}
return false
}
fun login() {
if (checkLogin()) {
ToastUtils.showToast(getApplication(), "suc!")
val old = username!!.value
old?.firstName = "null"
username?.postValue(old)
pwd = "null"
} else {
ToastUtils.showToast(getApplication(), "username=${username?.value!!.fullName.get()} pwd=${pwd}")
}
}
fun clickLogin(a: String) {
login()
Log.d("seekting", "DBViewModel.clickLogin()$a")
}
}
@Demo(group = [DemoGroup.JETPACK])
class DBActivity : AppCompatActivity() {
lateinit var mDbActivityBinding: DbActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDbActivityBinding = DataBindingUtil.setContentView(this, R.layout.db_activity)
mDbActivityBinding.mdbViewModel =
ViewModelProviders.of(this).get(DBViewModel::class.java)
mDbActivityBinding.lifecycleOwner = this
mDbActivityBinding.mdbViewModel?.username?.observe(this, object : Observer<UserName> {
override fun onChanged(t: UserName?) {
}
})
}
}
细节
达到双向绑定的要求:
- 使用
LiveData
- 要加上
mDbActivityBinding.lifecycleOwner = this
-
EditText
的更改导致user.firstName
的更改,fullName
也跟着更改,这时候FullName
的TextView
是不知道的,因为它不会user?.postValue(old)
需要把fullName变成ObservableField