I am trying to use DataBinding to add an Image to an ImageView.
I am fetching an object from a Room database and exposing the title and image URL as LiveData. I am able to set the title but the setting the image is failing.
Here's the error log
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter imageUrl
at com.sample.databinding.detail.ArticleDetailsViewModel$Companion.loadImage(Unknown Source:7)
at com.sample.databinding.detail.ArticleDetailsViewModel.loadImage(Unknown Source:2)
at com.sample.databinding.detail.databinding.ActivityArticleDetailsBindingImpl.executeBindings(ActivityArticleDetailsBindingImpl.java:198)
at androidx.databinding.ViewDataBinding.executeBindingsInternal(ViewDataBinding.java:448)
at androidx.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:420)
at androidx.databinding.ViewDataBinding$OnStartListener.onStart(ViewDataBinding.java:1633)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:215)
Here's the line in the generated file that is failing
if ((dirtyFlags & 0x19L) != 0) {
// api target 1
com.sample.databinding.detail.ArticleDetailsViewModel.loadImage(this.backdrop, articleDetailsViewModelImageUrlGetValue);
}
Here's my code
activity_details.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="articleDetailsViewModel"
type="com.monzo.androidtest.detail.ArticleDetailsViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:imageSource="@{articleDetailsViewModel.imageUrl}"/>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:title="@{articleDetailsViewModel.articleTitle}"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
ActivityDetailsViewModel.kt
package com.sample.databinding.detail
import android.app.Application
import android.widget.ImageView
import androidx.core.text.HtmlCompat
import androidx.databinding.BindingAdapter
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import com.bumptech.glide.Glide
import com.sample.databinding.articles.model.Article
import com.sample.databinding.data.ArticlesDao
import kotlinx.coroutines.*
class ArticleDetailsViewModel(
val database: ArticlesDao,
val application: Application,
val articleID: String) : ViewModel() {
val article = database.getSpecificPost(articleID)
val imageUrl = Transformations.map(article) {article.value?.thumbnail}
val articleTitle = Transformations.map(article) {article.value?.title}
companion object {
@JvmStatic
@BindingAdapter("bind:imageSource")
fun loadImage(view: ImageView, imageUrl: String) {
if (!imageUrl.isEmpty()) {
Glide.with(view.getContext())
.load(imageUrl)
.into(view)
}
}
}
}
See you have written a good code, but there is a problem in a Binding Adapter
@JvmStatic
@BindingAdapter("bind:imageSource")
fun loadImage(view: ImageView, imageUrl: String) {
if (!imageUrl.isEmpty()) {
Glide.with(view.getContext())
.load(imageUrl)
.into(view)
}
}
In this code you are expecting a not null imageUrl, but during run time, this value is null. So this is throwing an exception.
To solve this, you have to mention parameter imageUrl nullable. And then you have to check whether imageUrl is null or empty. So your binding adapter method will be like this :
@JvmStatic
@BindingAdapter("bind:imageSource")
fun loadImage(view: ImageView, imageUrl: String?) {
if (!imageUrl.isNullOrBlank()) {
Glide.with(view.getContext())
.load(imageUrl)
.into(view)
}
}
Hope this helps. Happy Coding :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With