StefanJo
StefanJo

Reputation: 285

Two-Way Binding - Data Binding Android

Okay so I'm experimenting with Two-Way Data binding right now, logically I think everything is perfect in the code, but somehow I keep getting the same error whenever I run the app: "A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution" . Basically I'm trying to hide ImageView visibility if there is no data in my database, using Data Binding ofc.

fragment_list.xml (Binding Layout)

<?xml version="1.0" encoding="utf-8"?>
<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="listViewModel"
            type="com.jovanovic.stefan.tododemo.fragments.list.ListViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/listLayout"
        ... >

        <ImageView
            android:id="@+id/no_data_imageView"
            emptyDatabase="@={listViewModel.emptyDatabase}"
            ... />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

ListViewModel (ViewModel for my Fragment)

class ListViewModel: ViewModel() {

    val emptyDatabase: MutableLiveData<Boolean> = MutableLiveData<Boolean>(true)

    fun checkDatabase(toDoData: List<ToDoData>){
        emptyDatabase.value = toDoData.isEmpty()
    }
}

ListFragment

class ListFragment : Fragment(), SearchView.OnQueryTextListener {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val listViewModel = ViewModelProvider(this).get(ListViewModel::class.java)
        val binding = FragmentListBinding.inflate(inflater, container, false)
        binding.lifecycleOwner = this
        binding.listViewModel = listViewModel

        val toDoViewModel= ViewModelProvider(this).get(ToDoViewModel::class.java)
        // Observing LiveData object for Room DB which is reading all data
        toDoViewModel.allData.observe(viewLifecycleOwner, Observer { data ->
            // Using checkDatabase method from ListViewModel
            listViewModel.checkDatabase(data)
        })

        return binding.root
    }

BindingAdapter

   @BindingAdapter("emptyDatabase")
   @JvmStatic
   fun emptyDatabase(view: View, emptyDatabase: MutableLiveData<Boolean>){
       if(emptyDatabase.value == true){
           view.visibility = View.VISIBLE
       }else{
           view.visibility = View.INVISIBLE
       }
   }

Upvotes: 0

Views: 633

Answers (3)

Shitul
Shitul

Reputation: 136

emptyDatabase="@={listViewModel.emptyDatabase}"

"=" is us only for android Model two way data binding."=" meaning if model update by get call its update view and if view update its update Model by set call .It's not applicable for databinding adaptor function

Upvotes: 1

StefanJo
StefanJo

Reputation: 285

After watching this video at (4:29) : https://youtu.be/TW9dSEgJIa8

I saw that I forgot to add this dependency for DataBinding:

//DataBinding
kapt "com.android.databinding:compiler:3.2.0-alpha10"

And even after I added that dependency, I still had an error, until I REMOVED "=" from "@={listViewModel.emptyDatabase}"

Upvotes: 0

Chaitanya Aggarwal
Chaitanya Aggarwal

Reputation: 21

I remember that I had similar problems with kapt. Please clean your build and try again, this works for me. Also as per the scenario you described for emptyDatabase.value == true, view.visibility should be View.Insivisble.

Upvotes: 0

Related Questions