【问题标题】:DataBinding causing a Kotlin compiler errorDataBinding 导致 Kotlin 编译器错误
【发布时间】:2018-11-13 09:55:12
【问题描述】:

我在 Bitbucket 中有以下分支:https://bitbucket.org/ali-rezaei/tmdb/src/dataBinding/

我在构建项目时遇到Kotlin compiler 错误:

e: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors.

错误与:

app:visibleGone="@{isLoaded}"

在以下布局中:

<layout 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">

    <data>
        <variable
            name="isLoaded"
            type="boolean" />
    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.MainActivity">

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:visibleGone="@{isLoaded}" />

        </android.support.v4.widget.SwipeRefreshLayout>

        <include
            layout="@layout/network_state_item"
            app:visibleGone="@{!isLoaded}" />

    </FrameLayout>

</layout>

如果您能帮助我,我将不胜感激。

【问题讨论】:

标签: android kotlin android-databinding


【解决方案1】:

我要做的改变是:这里

<variable
        name="isLoaded"
        type="boolean" />

我不会传递boolean,而是传递你的虚拟机实例

   <variable
        name="vm"
        type="com.sample.android.tmdb.ui.MovieViewModel" />

在你的片段中,你做

    mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
    mBinding?.setVariable(BR.vm, mViewModel)
    mBinding?.setLifecycleOwner(this)

这样,您的虚拟机将连接到片段的生命周期。

声明一个方法

  @BindingAdapter("visibleGone")
  fun View.visibleGone(visible: Boolean) {
      setVisibility(if (visible) View.VISIBLE else View.GONE)
  }

在您的MovieViewModel 中声明一个LiveData&lt;Boolean&gt; 变量并将其连接到您的布局中。例如。

 val loading: LiveData<Boolean>

那么在你的布局中你可以有

       <android.support.v7.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:visibleGone="@{!safeUnbox(vm.loading)}" />

【讨论】:

  • 谢谢,BR.vm 无法识别。我尝试了import com.android.databinding.library.baseAdapters.BRimport com.sample.android.tmdb.BR
  • 你建了吗?推送不同的分支并通过此处的链接
  • 是的,它与构建有关。现在我只得到 network_state_item 布局而不是 RecyclerView
  • 尝试将 android:layout_width android:layout_heightandroid:id 添加到包含中
【解决方案2】:

我遇到了一个稍微不同的问题,导致了这个错误。 在我的 ViewModel 中,我有以下方法:

`fun onSkip() {
    _score.value = (_score.value)?.minus(1)
    nextWord()
}`

现在,当我在我的 xml 中设置 onClick 属性时,我将它们设置为:

android:onClick="@{() -> gameViewModel.onSkip}" 

                 instead of

android:onClick="@{() -&gt; gameViewModel.onSkip()}"

请注意我是如何忘记在第一种方法中使用括号的。

【讨论】: