Required DataBindingComponent is null in class AgentDetailsActivityBindingImpl

in my agent_details_activity.xml:

 <ImageView
            android:id="@+id/imageViewPhoto"
            android:layout_width="0dp"
            android:layout_height="400dp"
            app:agentImageUrl="@{item.url}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/toolBarContainer" />

in activity:

class AgentDetailsActivity : AppCompatActivity() {
    private lateinit var binding: AgentDetailsActivityBinding

    companion object {
        val AGENT_DETAILS = AgentDetailsActivity::class.java.name + "_AGENT_DETAILS"
    }

    private val TAG = AgentDetailsActivity::class.java.name

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = AgentDetailsActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.setHandler(this);
    }

  @BindingAdapter("agentImageUrl")
    fun loadImage(view: ImageView, imageUrl: String) {
        Glide.with(view.context)
            .load(imageUrl)
            .apply(RequestOptions().error(R.drawable.no_image))
            .into(view)
    }

but in runtime I get error:

Shutting down VM
 FATAL EXCEPTION: main
 Process: com.android.testproject.android.kotlin.debug, PID: 24924
 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.testproject.android.kotlin.debug/com.android.testproject.android.kotlin.coroutine_retrofit.ui.activity.AgentDetailsActivity}: java.lang.IllegalStateException: Required DataBindingComponent is null in class AgentDetailsActivityBindingImpl. A BindingAdapter in com.android.testproject.android.kotlin.coroutine_retrofit.ui.activity.AgentDetailsActivity is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
    at android.app.ActivityThread.-wrap11(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 Caused by: java.lang.IllegalStateException: Required DataBindingComponent is null in class AgentDetailsActivityBindingImpl. A BindingAdapter in com.android.testproject.android.kotlin.coroutine_retrofit.ui.activity.AgentDetailsActivity is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
    at androidx.databinding.ViewDataBinding.ensureBindingComponentIsNotNull(ViewDataBinding.java:666)
    at com.android.testproject.android.kotlin.databinding.AgentDetailsActivityBindingImpl.<init>(AgentDetailsActivityBindingImpl.java:40)
    at com.android.testproject.android.kotlin.databinding.AgentDetailsActivityBindingImpl.<init>(AgentDetailsActivityBindingImpl.java:32)
    at com.android.testproject.android.kotlin.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:52)
    at androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
    at androidx.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
    at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:130)
    at androidx.databinding.ViewDataBinding.inflateInternal(ViewDataBinding.java:1366)
    at com.android.testproject.android.kotlin.databinding.AgentDetailsActivityBinding.inflate(AgentDetailsActivityBinding.java:95)
    at com.android.testproject.android.kotlin.databinding.AgentDetailsActivityBinding.inflate(AgentDetailsActivityBinding.java:81)
    at com.android.testproject.android.kotlin.coroutine_retrofit.ui.activity.AgentDetailsActivity.onCreate(AgentDetailsActivity.kt:37)
    at android.app.Activity.performCreate(Activity.java:6251)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)

To elaborate on @mahdi shahbazi answer (The bind adapter method must be static):

In kotlin, place your binding method outside of any class (so in your case oustide of the Activity class). This will do the trick. In your case, it will look like:

@BindingAdapter("agentImageUrl")
fun loadImage(view: ImageView, imageUrl: String) {
    Glide.with(view.context)
        .load(imageUrl)
        .apply(RequestOptions().error(R.drawable.no_image))
        .into(view)
}

class AgentDetailsActivity : AppCompatActivity() {
    private lateinit var binding: AgentDetailsActivityBinding

    companion object {
        val AGENT_DETAILS = AgentDetailsActivity::class.java.name + "_AGENT_DETAILS"
    }

    private val TAG = AgentDetailsActivity::class.java.name

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = AgentDetailsActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.setHandler(this);
    }

    ...

}

I have been able to come up with this answer thanks to this article: https://proandroiddev.com/custom-attributes-using-bindingadapters-in-kotlin-971ef8fcc259. There are lots of other good tips in it, I recommend looking into it for yummies about view binding.


In my case I found a really simple method, I had the same error as you. I just had to add @JvmStatic annotation.

The code will look something like this:

companion object {

     @JvmStatic // add this line !!
     @BindingAdapter("agentImageUrl")
        fun loadImage(view: ImageView, imageUrl: String) {
            Glide.with(view.context)
                .load(imageUrl)
                .apply(RequestOptions().error(R.drawable.no_image))
                .into(view)
        }
}