首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于EditText的双向数据绑定

基于EditText的双向数据绑定
EN

Stack Overflow用户
提问于 2017-09-29 17:47:17
回答 2查看 1.7K关注 0票数 1

我正在使用Kotlin开发一个简单的Android应用程序。我想使用数据库,但我无法让它们与EditText一起工作

这是我的XML布局

代码语言:javascript
复制
<?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>

这是我的模型课

代码语言:javascript
复制
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
}

这是将模型绑定到视图的部分。

代码语言:javascript
复制
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)
}

当我试图访问绑定中的模型属性时,我会得到一个空值。我使用的代码是

代码语言:javascript
复制
private fun save(): Boolean {
    try {
        val agency = binding.agency
        Log.d("Name", agency.name)
        return true
    } catch (ex: Exception) {
        return false
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-29 21:59:28

我发现了这个问题,它是由我绑定到错误的布局造成的。正确的代码如下。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2017-09-29 18:25:20

你并没有使用绑定的方式,它本来应该是Knerd。双向绑定的目的是让您可以从代码中访问对象或字段,而无需引用UI代码。通过执行binding.agency,您与findViewById()没有什么不同,并且您正在破坏绑定的目的。

首先修复绑定问题。对您的对象模型使用BaseObservable,它应该与屏幕上任何值的变化保持同步。

那么,当您保存时,应该只是访问局部变量。

代码语言:javascript
复制
private fun save(): Boolean {
    try {

        Log.d("Name", localObservableAgency.name)
        return true
    } catch (ex: Exception) {
        return false
    }
}

//不确定此方法的作用,猜测您正在尝试捕获null。更好的方法是对对象执行空检查,因为通过访问空值捕获异常很重,而且不增加值。此外,Kotlin是空安全语言,所以您要么在绑定上丢失了值,要么将其设置为null,或者在这里进行奇怪的编码,因为如果保留本地副本,则必须故意使对象为空。但是,您并没有保存本地副本--只是将一个副本内联起来,然后通过绑定进行访问,就好像它是您的变量存储库一样。

长话短说,就是使用数据绑定的方式,您将不会有任何问题。也许这就是为什么有人投了你的票是我的猜测。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46494358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档