Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 234
Alexei Avatar asked Sep 22 '19 12:09

Alexei


4 Answers

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)
        }
}
like image 74
clauub Avatar answered Nov 20 '22 08:11

clauub


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.

like image 36
Mel' Avatar answered Nov 20 '22 07:11

Mel'


Yes, first of all place your binding method outside of any class. Second, make imageUrl nullable! Becouse if you will have imageUrl is null you will have crash instead of onError is invoked

@BindingAdapter("agentImageUrl")
fun loadImage(view: ImageView, imageUrl: String?) {
    Glide.with(view.context)
        .load(imageUrl)
        .apply(RequestOptions().error(R.drawable.no_image))
        .into(view)
}
like image 7
Viktor Burmaka Avatar answered Nov 20 '22 07:11

Viktor Burmaka


    // Solution 1
@BindingAdapter("android:loadImage")
fun loadImage(userImageView: ImageView, imageUrl: String): Unit {
    Glide
        .with(userImageView)
        .load(imageUrl)
        .into(userImageView)
}

**This is my solution, I have written my function outside the class**
like image 6
Mr. Tayyab MuGhal Avatar answered Nov 20 '22 09:11

Mr. Tayyab MuGhal