Ali
Ali

Reputation: 9994

DataBinding causing a Kotlin compiler error

I have following branch in Bitbucket : https://bitbucket.org/ali-rezaei/tmdb/src/dataBinding/

I get following Kotlin compiler error when I build the project :

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

Error is related to :

app:visibleGone="@{isLoaded}"

in the following layout :

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

I appreciate if you can help me out.

Upvotes: 1

Views: 1182

Answers (2)

Beast77
Beast77

Reputation: 223

I had a slightly different problem that generated this error. In my ViewModel, I had the following method:

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

Now, when i was setting the onClick attributes in my xml, I set them like this:

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

                 instead of

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

Notice how I forgot to use the parenthesis in the first method.

Upvotes: 0

Blackbelt
Blackbelt

Reputation: 157487

The changes I would do are: Here

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

Instead of passing boolean I would pass an instance of your VM

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

in your fragment, you do

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

this way, your VM is connected to the lifecycle of your fragment.

Declare a method

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

declare a LiveData<Boolean> variable in you MovieViewModel and connect it in your layout. Eg.

 val loading: LiveData<Boolean>

then in your layout you could have

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

Upvotes: 3

Related Questions