【问题标题】:Android Two Way Databinding working only one wayAndroid 双向数据绑定仅以一种方式工作
【发布时间】:2019-09-29 22:22:36
【问题描述】:

我有 ViewModel:

class MyViewModel : ViewModel(){
    private val _user = MutableLiveData("")

    val user: LiveData<String> = _user

    fun onBtnClick(){
        Log.i("MyViewModel", "user: ${_user.value}")
    }
}

我使用以下方法将其与片段布局连接:

<data>
    <variable
        name="viewmodel"
        type="com.pkg.pkg.pkg.fragments.concretePkg.MyViewModel" />
</data>
<EditText
    ...
    android:text="@={viewmodel.user}"
    android:hint="User" />

在片段类的onCreateView方法中:

binding = DataBindingUtil.inflate(inflater, R.layout.fragment_my_fragment, container, false)
binding.lifecycleOwner = this
// bind viewModel
viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
binding.viewmodel = viewModel

// Inflate the layout for this fragment
return binding.root

我可以从片段或 ViewModel 类更改 EditText 值,但是当我尝试在 Logcat 中的 ViewModel 的 onBtnClick 方法中获取值时,我收到消息:I/MyViewModel: user: 我在这里缺少什么,以便双向数据绑定也可以从另一个方向工作? 简而言之,数据从界面上的 ViewModel/ Fragment 流向 EditText,但它不会从界面上的 EditText 流向 ViewModel 字段/方法。 提前致谢。

------- 已编辑 ----- 我设法填充了所有内容,但知道我收到了这个错误:

Details: There is no inverse for method getValue, you must add an @InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions

我想这是因为 viewmodel.user 是 LiveData 类型而不是 String 类型。我已经写了绑定适配器:

@BindingAdapter("android:text")
    fun setLiveDataText(editText: EditText, liveData: LiveData<String>) {
            if(liveData == null){
                editText.setText("")
            } else {
                editText.setText(liveData.value)
            }
        }

但我仍然收到上述消息。

【问题讨论】:

    标签: android kotlin data-binding mutablelivedata android-components


    【解决方案1】:

    首先,您需要公开_user。然后需要使用"@={viewmodel._user}",这样就可以得到_user的值。如果您不公开数据绑定变量,则数据绑定 API 无法计算并生成代码。对于字符串等简单字段,这种方法就足够了,但对于更复杂的情况,您可能必须实现BindingAdapters。有关示例,请参阅this 文章。

    【讨论】:

    • 我已经看到了,并输入了 '@=' 但它会产生错误:符号:类 FragmentMyFragmentBindingImpl 位置:包 com.pkg.pkg.databinding
    • @M.Vas,编辑了我的答案,因为您在视图模型中命名了变量 _user,因此您还必须在 XML 中使用带有下划线的确切名称
    • 谢谢,我已经编辑了我的问题,因为在评论中回答太长了。
    • 谢谢。只需要放一个=,我的生命就得救了。多谢。找了这么久几乎放弃了。
    【解决方案2】:

    要解决这个问题,您应该将其添加到 build.gradle:

    implementation "android.arch.lifecycle:extensions:1.1.1"
    

    而且kotlin版本应该降级了:

    ext.kotlin_version = '1.3.41'
    

    干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 2019-01-29
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多