使用DataBindingComponent的膨胀方法

use*_*966 5 data-binding android mvvm android-databinding

一旦Glide成功渲染了图像,我在更新textview时会看到此错误。

致命异常:java.lang.IllegalStateException:类CustomBinding中必需的DataBindingComponent为null。CustomViewModel中的BindingAdapter不是静态的,需要使用一个从DataBindingComponent检索的对象。如果您不使用带DataBindingComponent的膨胀方法,请使用DataBindingUtil.setDefaultComponent或将所有BindingAdapter方法设为静态。

@BindingAdapter(value = { "android:src", "placeHolder" }, requireAll = false) 
public void setUrl(ImageView imageView, String url, Drawable placeHolder) {
          Glide.with(imageView.getContext())
              .load(url)
              .placeholder(placeHolder)
              .centerCrop()
              .listener(new Listener<String, Drawable>() {
                @Override
                public boolean onException() {
                  viewmodel.setTextVisible(true);// ERROR!
                  return false;
                }

                @Override public boolean onResourceReady() {
                  viewmodel.setTextVisible(false); // ERROR!
                  return false;
                }
              })
              .into(imageView);
        }

public void setTextVisible(boolean visibility) {
    textVisibility = visibility;
    notifyPropertyChanged(BR.textVisibility);
}

    @Bindable 
    public boolean getTextVisible() {
      return textVisibility; 
    }
Run Code Online (Sandbox Code Playgroud)

这是我初始化视图模型并将数据绑定到片段内的方式:

CustomBinding binding =
        DataBindingUtil.inflate(inflater, R.layout.custom, container, 
false);

    CustomViewModel viewModel = new CustomViewModel(data, context);
    binding.setHandlers(new CustomHandlers(context));
    binding.setData(viewModel);
Run Code Online (Sandbox Code Playgroud)

我找不到在ViewModel中实际实现此方法的方法。在此先感谢您的帮助。

vik*_*mar 6

面对相同的问题,通过@JvmStatic在方法中添加注释来解决该问题,并且 该方法可以正常工作。

它应该是形式

@BindingAdapter(“ app:someAttribute”)

@JvmStatic

class TestBindingHelper {

    companion object{

        @BindingAdapter("app:serviceOptions")
        @JvmStatic
        fun setServiceOptions(recyclerView: RecyclerView, listOfData: List<String>?) {
             //do something funny
        }

    }
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*der 3

您的错误告诉您,您创建的适配器不是静态的,但它必须是静态的。
我不太确定直接从绑定适配器更改视图模型是否是一个好的尝试。
将每个绑定适配器视为独立的静态方法,该方法位于单独的类(例如 BindingUtils)中,并且可以使用您传递给它的参数进行工作。
在您的示例中,不清楚如何传递 URL 本身(我猜不是通过 android:src)。
在此示例中,适配器处理 ImageView、图像 url 和错误可绘制对象:

/**
 * Loads image from url and sets it into the Image View
 * with error drawable (set into imageview if failed to load the image)
 *
 * @param imageView       {@link ImageView}
 * @param url             image url
 * @param errorDrawable   Drawable to set in case of load error.
 */
@BindingAdapter({"bind:imageUrlRound", "bind:imageError"})
public static void loadRoundImage(ImageView imageView, String url, Drawable errorDrawable) {
    Glide.with(imageView.getContext())
            .load(url)
            .asBitmap()
            .error(errorDrawable)
            .centerCrop()
            .animate(R.anim.fade_in)
            .into(new BitmapImageViewTarget(imageView) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable =
                            RoundedBitmapDrawableFactory.create(imageView.getContext().getResources(), resource);
                    circularBitmapDrawable.setCircular(true);
                    imageView.setImageDrawable(circularBitmapDrawable);
                }
            });
}
Run Code Online (Sandbox Code Playgroud)

布局看起来像什么:

<ImageView
...
app:imageUrlRound="@{yourViewModel.image}"
app:imageError="@{@drawable/ic_error}" />
Run Code Online (Sandbox Code Playgroud)

我不确定这是一个好的实践,但是您可以尝试将视图模型添加为另一个绑定属性以及适配器的参数,并在滑行的回调中更改它的参数。
PS 还简化您的视图模型(创建一个映射器以方便使用)以仅包含您想要在布局中显示的参数(即字符串整数等)恕我直言,在那里传递上下文很奇怪......