使用Android双向数据绑定时,我必须在BindingAdapter
上使用静态View
还是以某种方式简单地使用可观察的实例字段?在文档中,我始终只能在ViewModel
上看到可观察的字段,而在View
上却看不到。我尝试使用{p>在我的View
上实现可观察字段
var myValue: String = ""
@Bindable get(): String {
return field
}
set(value: String) {
field=value
setText(value)
notifyPropertyChanged(BR.myValue) // my View implements the Observable interface
}
但是当我编译它(使用./gradlew assembleDebug --stacktrace
来获取详细信息)时,它失败了
ERROR: Cannot find a getter for <com.example.test.MyAutoCompleteTextView app:myValue>
that accepts parameter type 'java.lang.String'
If a binding adapter provides the getter, check that the adapter is annotated correctly
and that the parameter type matches.
因此,是否不可能像在View
上那样在双向数据绑定的ViewModel
侧上使用可观察字段?我想使用可观察字段而不是静态BindingAdapter
的原因是我的View
具有比我在BindingAdapter
中无法处理的逻辑/状态更复杂的逻辑/状态(嗯,从静态{ {1}}我可以打电话给BindingAdapter
,但在某种程度上对我来说是错的)
更新
我建立了一个最低限度的工作示例available on Github 默认情况下,它使用单向绑定,效果很好。更改
myViewInstance.myValue
到
app:myValue="@{viewModel.realValue}"
app:myValue="@={viewModel.realValue}"
中的将导致编译信息错误。使用activity_main.xml
获得长输出,其中包括
./gradlew assembleDebug --stacktrace
谁能看看这个,让我知道我在做什么错?
答案 0 :(得分:1)
使用Android双向数据绑定时,我是否必须在View上使用静态BindingAdapters,还是可以以某种方式简单地使用可观察的实例字段?
我认为您可以使用Observable实例字段来完成此操作。但是如果此逻辑也正在其他地方重用,我个人更喜欢使用BindingAdapters
。
在您的Observable类中,将代码修改为此:
@get:Bindable
var myValue: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.myValue) // my View implements the Observable interface
}
我检查了您的存储库,发现您现在正在使用MutableLiveData,因此在这种情况下您不需要上面的代码。我也在那里找不到任何BindingAdapter。确保您的代码BindingAdapter看起来像这样:
@BindingAdapter("myValue")
@JvmStatic
fun TextView.setMyValue(realValue: String) {
val finalValue : String = realValue.dataManipulation() // Do your data manipulation here
setText(finalValue) // Make sure it's a string
}
最后,您的XML TextView应该看起来像这样:
<com.example.test.MyAutoCompleteTextView
...
app:myValue="@{viewModel.realValue}"
... />
让我知道这是否有效。
编辑
所以我们要寻找的基本上是BaseObservable类中的Bindable变量。让我们专注于三件事:XML,活动/片段和BindingModel类。
您的BindingModel类基本上扩展了BaseObservable类。
class BindingModel: BaseObservable(){
@get:Bindable
var myValue: String = ""
set(value) {
var finalValue = manipulateData(value) //Write your logic here
field = finalValue
notifyPropertyChanged(BR.myValue) // my View implements the Observable interface
}
...
}
在“活动/片段”中,创建BindingModel
类型的变量。观察LiveData并更新变量。
class MainActivity : AppCompatActivity() {
...
val model = BindingModel()
...
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.lifecycleOwner = this // Specify the current activity as the lifecycle owner.
binding.model = model
viewModel.realValue.observe(this, Observer {
model.myValue = it
})
} // End of onCreate()
...
} // End of Activity code
继续使用XML,您需要在其中声明model
数据绑定变量。
...
<data>
...
<variable
name="model" //Make sure the name is same
type="com.example.test.<path-to-your-file>.BindingModel" />
</data>
...
<com.example.test.MyAutoCompleteTextView
...
android:text="@{model.realValue}" //Don't forget this
... />
瞧!它应该工作。让我知道是否可以。