【问题标题】:Inflate method using DataBindingComponent使用 DataBindingComponent 的膨胀方法
【发布时间】:2018-02-06 13:52:41
【问题描述】:

在 Glide 成功渲染图像后,我在更新文本视图时看到此错误。

致命异常:java.lang.IllegalStateException:必需 类 CustomBinding 中的 DataBindingComponent 为空。一个绑定适配器 在 CustomViewModel 中不是静态的,需要一个对象才能使用, 从 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; 
    }

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

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

    CustomViewModel viewModel = new CustomViewModel(data, context);
    binding.setHandlers(new CustomHandlers(context));
    binding.setData(viewModel);

我找不到在视图模型中实际实现此功能的方法。提前感谢您的帮助。

【问题讨论】:

  • 您到底想实现什么?滑动加载图片失败时是否要隐藏另一个TextView?
  • 是的@LeoDroidcoder

标签: android mvvm data-binding android-databinding


【解决方案1】:

您的错误表明您创建的适配器不是静态的,但它必须是静态的。
我不太确定直接从绑定适配器更改视图模型是否是一个很好的尝试。
将每个绑定适配器视为一个独立的静态方法,它位于一个单独的类(例如 BindingUtills)中,它可以处理您传递给它的参数。
在您的示例中,尚不清楚您如何传递 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);
                }
            });
}

布局是什么样子的:

<ImageView
...
app:imageUrlRound="@{yourViewModel.image}"
app:imageError="@{@drawable/ic_error}" />

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

【讨论】:

  • 静态方法可以采用图像视图,并且绑定适配器的所有各种参数部分都应该是该特定视图的属性。所以我不确定是否可以将 textview 作为另一个属性。
  • TextView 不能是另一个属性!但是您可以尝试向那里传递一个变量(您之前设置的)并在适配器中更改它。
  • 即你有一个对象用户,你做了 binding.setUser(user)。然后将其作为属性传递,例如 app:userAttr="@{user}"。然后在适配器中根据您的需要更改用户字段:user.setTextVisible(true)(textVisible 是用户的字段)。
  • 然后让 TextView 的可见性依赖于 user.textVisible。这应该工作
  • 变量看起来像
【解决方案2】:

遇到了同样的问题,通过在方法中添加@JvmStatic 注释得到解决,它可以工作。

应该是格式

@BindingAdapter("app:someAttribute")

@JvmStatic

示例

class TestBindingHelper {

    companion object{

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

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多