android - 如何使用数据绑定(bind)将数据绑定(bind)到 RecyclerView 中的一行?

标签 android android-recyclerview android-databinding

我想使用数据绑定(bind)在 RecyclerView 行中显示一些图像和文本。代码运行没有任何错误,但数据未显示在 RecyclerView 中。

reward_item.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>
            <import type="android.view.View" />
            <variable
                name="recipes"
                type="com.prasona.android.indiancusine.Model.NameModel" />
        </data>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:cardElevation="5dp"
                app:cardUseCompatPadding="true">


                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:id="@+id/name_textView"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:layout_marginLeft="10dp"
                        android:layout_toEndOf="@+id/recipeimageView"
                        android:layout_toRightOf="@+id/recipeimageView"
                        android:text="@{recipes.recipeName}"
                        android:textColor="@android:color/black"
                        android:textSize="18sp" />

                    <ImageView
                        android:id="@+id/recipeimageView"
                        android:layout_width="180dp"
                        android:layout_height="180dp"
                        android:layout_alignParentLeft="true"
                        android:layout_alignParentStart="true"
                        android:layout_alignParentTop="true"
                        app:srcCompat="@drawable/dinner"
                        app:imageUrl="@{image.imageUrl}"/>
                </RelativeLayout>
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </layout>

这是我的适配器:

import android.databinding.BindingAdapter;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;


import java.util.List;

/**
 * Created by admin on 14-12-2017.
 */

public class RewardAdapter extends RecyclerView.Adapter<RewardAdapter.ViewHolder> {
    private List<SampleModel> model;

    public RewardAdapter(List<SampleModel> model) {
        this.model = model;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),
                R.layout.rewarded_item, parent, false);

        return new ViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        ViewDataBinding viewDataBinding = holder.getViewDataBinding();

//        viewDataBinding.setVariable(BR.image,model.get(position));
        viewDataBinding.setVariable(BR.recipeName, model.get(position));
        viewDataBinding.setVariable(BR.imageUrl, model.get(position));
    }

    @Override
    public int getItemCount() {
        return (null != model ? model.size() : 0);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private ViewDataBinding viewBinding;

        public ViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());

            viewBinding = binding;
            viewBinding.executePendingBindings();
        }

        public ViewDataBinding getViewDataBinding() {
            return viewBinding;
        }
    }


}

最佳答案

根本不清楚您要绑定(bind)什么。在您的代码中,您有 SampleModel 类,它似乎是您行的模型,但在您的布局中,您已经声明了一个 Model.NameModel 类型的变量配方。稍后在行布局中,您还为 ImageView 使用图像变量。

我假设您的行模型是您在适配器中使用的 SampleModel 类,并且它包含文本(对于 TextView)和一个表示该条目的图像 url 的字符串。要使绑定(bind)工作,您应该:

在代码中声明一个 SampleModel 变量并将其用于您的 View :

<data>
    <import type="android.view.View" />
    <variable
        name="recipes"
        type="the.package.of.the.class.SampleModel" />
</data>

将在布局中使用:

<TextView
    ...
    android:text="@{recipes.recipeName}"/>
<ImageView
    ...
    app:imageUrl="@{recipes.imageUrl}"/>

SampleModel 类应该是一个扩展 BaseObservable 并公开我们上面使用的两个字段的类:

class SampleModel extends BaseObservable {
    private String recipeName;
    private String imageUrl;

    @Bindable
    public String getRecipeName() {
         return recipeName;
    }

    @Bindable
    public String getImageUrl() {
         return imageUrl;
    }
}

需要更改适配器以使用确切的绑定(bind)类:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    RewardItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),
            R.layout.rewarded_item, parent, false);
    // update the ViewHolder constructor to receive a RewardItemBinding parameter instead of the super class
    return new ViewHolder(binding);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    RewardItemBinding viewDataBinding = holder.getViewDataBinding();
    viewDataBinding.setRecipes(model.get(position));
}

这将为模型中的两个 View 设置数据。问题在于 ImageView 没有我们在布局中使用的 imageUrl 属性的 setter ,绑定(bind)框架不知道如何将数据绑定(bind)到 View 。要处理此问题,您可以使用如下所示的 BindingAdapter:

// declare this method in one of your classes(notice the static modifier)
@BindingAdapter("imageUrl")
public static void bindImage(ImageView imageView, String imageUrl) {
    // use Glide to setup the image
}

关于android - 如何使用数据绑定(bind)将数据绑定(bind)到 RecyclerView 中的一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47864201/

相关文章:

java - token 语法错误,预期 ConstructorHeaderName 和 token 语法错误 "(",< 预期

android - 我想在 Recyclerview 适配器中检查小于或等于零的数量,但在 Android 中不起作用

android - 如何将 Hashmap<String,List<Items>> 膨胀到 Recyclerview

Android - 为什么在滚动 RecyclerView 时丢失值 EditText?

android - 数据绑定(bind)错误:(421, 17)错误: variable xyzViewHand is already defined in method _internalCallbackOnClick(int,查看)

android - 当另一个 Activity 启动时,Phonegap 应用程序将关闭。为什么?

将 sqlite 数据库发送到服务器的 Android 实用程序

属性 app :itemIconTint will be ignored 的 Android 数据绑定(bind)应用程序命名空间

javascript - 我可以在 Android 开发中使用 javax.script 吗?如果可以,如何使用?

android - 将 Gradle 升级到 3.5.1 时数据绑定(bind)停止工作