I have a recyclerview that displays a list of data. It has normal content for its rows as well as a footer. I don't see anything wrong in my code but when I try to build the project then I get the following error. I tried to clear the cache and invalidate my Android Studio but no luck. I still get the similar error in the console.
> Task :app:kaptDebugKotlin
/home/hesam/apps/projects/atco/rumi-android/app/build/generated/source/kapt/debug/com/atco/rumi/DataBinderMapperImpl.java:15: error: cannot find symbol
import com.atco.rumi.databinding.RowAboutItemBindingImpl;
^
symbol: class RowAboutItemBindingImpl
location: package com.atco.rumi.databinding
> Task :app:kaptDebugKotlin FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
> java.lang.reflect.InvocationTargetException (no error message)
I spent a few hours figuring out what is the problem but I couldn't. Does it compiler issue?
I do have databinding enabled in my app/build.gradle file.
...
dataBinding {
enabled = true
}
...
This is my adapter class:
import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.atco.rumi.BuildConfig
import com.atco.rumi.databinding.RowAboutFooterBinding
import com.atco.rumi.databinding.RowAboutItemBinding
data class AboutItem(
val title: String,
val icon: Drawable?,
val webUrl: String
)
data class AboutFooter(
val version: String
)
class AboutAdapter(
val context: Context
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val items: List<AboutItem> = getAboutItems(context)
companion object {
const val TYPE_HEADER = 0
const val TYPE_FOOTER = 1
const val TYPE_ITEM = 2
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
TYPE_ITEM -> {
val binding = RowAboutItemBinding.inflate(inflater)
ItemViewHolder(binding)
}
TYPE_FOOTER -> {
val binding = RowAboutFooterBinding.inflate(inflater)
FooterViewHolder(binding)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is FooterViewHolder -> {
val version = getFormattedVersion(context, BuildConfig.VERSION_NAME)
val item = AboutFooter(version)
holder.bindItem(item)
}
is ItemViewHolder -> holder.bindItem(items[position], position)
else -> throw IllegalArgumentException()
}
}
override fun getItemCount(): Int {
return items.size + 1 // Because we need to append the Footer
}
override fun getItemViewType(position: Int): Int {
if (position == 0 && items.isEmpty()) return TYPE_FOOTER
if (position == items.size) return TYPE_FOOTER
return TYPE_ITEM
}
inner class ItemViewHolder(val binding: RowAboutItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(item: AboutItem, position: Int) {
binding.item = item
binding.aboutItemContainer.setOnClickListener {
// TODO: Implement it
}
binding.executePendingBindings()
}
}
inner class FooterViewHolder(val binding: RowAboutFooterBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(item: AboutFooter) {
binding.item = item
binding.executePendingBindings()
}
}
}
this is my row_about_item.xml file:
<?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="item"
type="com.atco.rumi.scenes.tabs.about.AboutItem" />
</data>
<LinearLayout
android:id="@+id/aboutItemContainer"
style="@style/about_action_click">
<ImageView
android:id="@+id/imageView"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_marginEnd="30dp"
app:srcCompat="@{item.icon}" />
<TextView
android:id="@+id/textView"
style="@style/about_textView"
android:text="@{item.title}"
tools:text="This is the title" />
</LinearLayout>
</layout>
and finally, this is my row_about_footer.xml:
<?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="item"
type="com.atco.rumi.scenes.tabs.about.AboutFooter" />
</data>
<LinearLayout style="@style/about_action_click">
<TextView
android:id="@+id/textView"
style="@style/about_textView_footer"
android:layout_marginStart="60dp"
android:text="@{item.version}"
tools:text="Version 1.0" />
</LinearLayout>
</layout>
The suspect is srcCompat=@{item.icon}
, as I'm not sure what exactly databinding generates for srcCompat (if anything). So I believe if you change this to
<ImageView
...
android:src="@{item.icon}"
/>
this will work. If not, then you probably need to go for a custom binding adapter.