IllegalArgumentException при использовании DataBinding для ImageView с использованием LiveData - PullRequest
0 голосов
/ 09 апреля 2019

Я пытаюсь использовать DataBinding, чтобы добавить изображение в ImageView.

Я извлекаю объект из базы данных Room и выставляю заголовок и URL изображения как LiveData.Я могу установить заголовок, но настройка изображения не удалась.

Вот журнал ошибок

 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)

Вот строка в сгенерированном файле с ошибкой

if ((dirtyFlags & 0x19L) != 0) {
        // api target 1

        com.sample.databinding.detail.ArticleDetailsViewModel.loadImage(this.backdrop, articleDetailsViewModelImageUrlGetValue);
    }

Вот мой код

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)

            }

        }
    }
}

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

Видите, вы написали хороший код, но есть проблема в адаптере Binding

   @JvmStatic
        @BindingAdapter("bind:imageSource")
        fun loadImage(view: ImageView, imageUrl: String) {
            if (!imageUrl.isEmpty()) {
                Glide.with(view.getContext())
                        .load(imageUrl)
                        .into(view)
            }
        }

В этом коде вы ожидаете не ноль imageUrl , но во время выполнения это значение равно нулю. Так что это исключение.

Чтобы решить эту проблему, вы должны упомянуть параметр imageUrl nullable. И затем вы должны проверить, является ли imageUrl нулевым или пустым. Таким образом, ваш метод адаптера привязки будет таким:

 @JvmStatic
        @BindingAdapter("bind:imageSource")
        fun loadImage(view: ImageView, imageUrl: String?) {
            if (!imageUrl.isNullOrBlank()) {
                Glide.with(view.getContext())
                        .load(imageUrl)
                        .into(view)
            }
        }

Надеюсь, это поможет. Удачного кодирования:)

1 голос
/ 09 апреля 2019

должно быть

imageUrl?.let {
     Glide.with(view.getContext())
          .load(imageUrl)
          .into(view)
}
...