我正在使用Kotlin开发一个简单的Android应用程序。我想使用数据绑定,但我无法使用EditText
这是我的XML布局
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="de.knerd.applicationmanager.models.AgencyModel"/>
<variable name="agency" type="AgencyModel"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_add_agency"
tools:context="de.knerd.applicationmanager.activities.AddAgencyActivity"
android:orientation="vertical"
android:layout_margin="16dp">
<android.support.design.widget.TextInputLayout android:layout_height="match_parent"
android:layout_width="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="@+id/name"
android:labelFor="@+id/name"
android:hint="@string/agency_name"
android:text="@={agency.name}"/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
</layout>
这是我的Model类
package de.knerd.applicationmanager.models
import android.databinding.BaseObservable
import android.databinding.Bindable
import com.j256.ormlite.dao.ForeignCollection
import com.j256.ormlite.field.DatabaseField
import com.j256.ormlite.field.ForeignCollectionField
import com.j256.ormlite.table.DatabaseTable
import de.knerd.applicationmanager.BR
@DatabaseTable(tableName = "agency")
class AgencyModel : BaseObservable() {
@DatabaseField(unique = true, canBeNull = false)
@get:Bindable
@set:Bindable
var name: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.name)
}
@DatabaseField(generatedId = true)
@get:Bindable
var id: Int = 0
@ForeignCollectionField(eager = false)
@get:Bindable
var agents: ForeignCollection<AgentModel>? = null
}
这是将模型绑定到视图的部分
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ContentAddAgencyBinding>(this, R.layout.content_add_agency)
binding.agency = AgencyModel()
setContentView(R.layout.activity_add_agency)
val toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
当我尝试访问绑定中的模型属性时,我得到一个空值。我使用的代码就是这个
private fun save(): Boolean {
try {
val agency = binding.agency
Log.d("Name", agency.name)
return true
} catch (ex: Exception) {
return false
}
}
答案 0 :(得分:1)
我发现了问题,这是由于我绑定到错误的布局造成的。正确的代码如下。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityAddAgencyBinding>(this, R.layout.activity_add_agency)
binding.agency = AgencyModel()
val toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
在这两种情况下,我都必须绑定到活动布局
答案 1 :(得分:0)
你没有按照Knerd的方式使用Binding。双向绑定旨在使您可以从代码访问对象或字段,而无需引用UI代码。通过你执行binding.agency你和findViewById()没什么不同,你就是在破坏绑定的目的。
首先修复绑定问题。使用BaseObservable作为对象模型,它应该与屏幕上的任何值更改保持同步。
然后当你保存时,它应该只是访问本地变量。
private fun save(): Boolean {
try {
Log.d("Name", localObservableAgency.name)
return true
} catch (ex: Exception) {
return false
}
}
//不确定这个方法是什么,猜测你是尝试捕获null。更好的方法是对对象进行空检查,因为访问空值很重,并且不会增加值。此外,Kotlin是一种空的安全语言,所以你要么在绑定上失去你的价值,也可以通过将它设置为null来开始,或者在这里奇怪地编码一些东西,因为如果你保留一个本地副本,你必须故意使一个对象可以为空。但是,你并没有保留一个本地副本,你只需要新建一个内联副本,然后通过绑定访问,就好像它是你的变量存储库哈哈。
长话短说,使用数据绑定的方式是打算使用它并且你不会遇到问题。这可能就是为什么有人拒绝投票给你的原因。