DataBinding(二)

DataBinding(二)

1. 列表绑定

以RecyclerView为例,主要变化在子项布局和适配器。

1. 将子项布局改为DataBinding布局

public class Dishes {

    private String imgAdress;
    private String name;

    public Dishes(String imgAdress, String name) {
        this.imgAdress = imgAdress;
        this.name = name;
    }

    public String getImgAdress() {
        return imgAdress;
    }

    public void setImgAdress(String imgAdress) {
        this.imgAdress = imgAdress;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
<?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">

    <data>
        
    </data>

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

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/item_cv"
            android:layout_marginTop="5dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginBottom="5dp"
            app:cardCornerRadius="10dp"
            app:cardElevation="5dp"
            android:layout_width="match_parent"
            android:layout_height="225dp">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ImageView
                    android:id="@+id/id_dishes_img"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    android:layout_marginLeft="8dp"
                    android:layout_gravity="center_vertical"
                    android:layout_width="200dp"
                    android:layout_height="200dp"
                    android:scaleType="centerCrop"
                    app:imageUrl="@{dishes.imgAdress}"/>

                <TextView
                    android:id="@+id/id_dishes_title"
                    android:layout_marginLeft="8dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintLeft_toRightOf="@id/id_dishes_img"
                    app:layout_constraintVertical_bias="0.3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@{dishes.name}"
                    android:textStyle="bold"
                    android:textSize="28sp"
                    android:lines="2" />
            </androidx.constraintlayout.widget.ConstraintLayout>

        </com.google.android.material.card.MaterialCardView>
    </LinearLayout>
</layout>

布局中设置一个CardView,包含一个TextView和一个ImageView

2. 适配器

适配器的改变主要在ViewHolder。

public class DishesAdapter extends RecyclerView.Adapter<DishesAdapter.BindingViewHolder>{

    private DishesClickListener listener;
    private LayoutInflater inflater;
    private List<Dishes> list;

    public DishesAdapter(Context context) {
        inflater = LayoutInflater.from(context);
        list = new ArrayList<>();
    }

    static class BindingViewHolder<T extends ViewDataBinding>
            extends RecyclerView.ViewHolder{

        private T binding;
        public BindingViewHolder(T binding) {
            super(binding.getRoot());
            this.binding=binding;
        }

        public T getBinding() {
            return binding;
        }
    }
    @NonNull
    @Override
    public BindingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ViewDataBinding binding;
        binding = DataBindingUtil.inflate(inflater, R.layout.dishes_list_item,parent,false);
        return new BindingViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull BindingViewHolder holder, int position) {
        Dishes dishes = list.get(position);
        ViewDataBinding binding = holder.getBinding();
        binding.setVariable(BR.dishes,dishes);
        binding.executePendingBindings();
        holder.itemView.setOnClickListener(v -> listener.onClick(dishes));

    }

    public void addAll(List<Dishes> dishes){
        list.addAll(dishes);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public void setListener(DishesClickListener listener){
        this.listener = listener;
    }

    public interface DishesClickListener{
        void onClick(Dishes dishes);
    }


}

之前的RecyclerView的适配器,ViewHolder中有布局中的控件,现在我们结合DataBinding,ViewHolder中只需要有ViewDataBinding,再通过ViewDataBinding将数据set到布局中去。

  • onCreateViewHolder()

这行代码binding = DataBindingUtil.inflate(inflater, R.layout.dishes_list_item,parent,false);相当于原来View = inflater.inflate(R.layout.dishes_list_item,parent,false);不同的是,会返回一个ViewDataBinding

  • onBindViewHolder()

ViewDataBinding binding = holder.getBinding();

binding.setVariable(BR.dishes,dishes);

首先获取ViewDataBinding,然后将数据set进去。

binding.executePendingBindings();

对数据做一个及时的刷新。

2. 自定义属性

  • @BindingAdapter
<ImageView
    android:id="@+id/id_dishes_img"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:scaleType="centerCrop"
    app:imageUrl="@{}"/>
@BindingAdapter("imageUrl")
public static void setImageUrl(ImageView imageView,String url){
    Glide.with(imageView).load(Uri.parse(url)).into(imageView);
}

当用@BindingAdapter注解方法时,该方法必须声明为 public static

参数:第一个是绑定的控件,第二个参数就是可传来的自定义参数。


多参数

<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/id_xuri_rv"
    app:adapter="@{adapter}"
    app:layoutManager="@{manager}"/>
@BindingAdapter(value = {"adapter","layoutManager"})
public static void setAdapterAndManager(RecyclerView recyclerView, DishesAdapter adapter, RecyclerView.LayoutManager manager){
    recyclerView.setLayoutManager(manager);
    recyclerView.setAdapter(adapter);
}
@BindingAdapter(value = {"adapter","layoutManager"},requireAll = false)
public static void setAdapterAndManager(RecyclerView recyclerView, DishesAdapter adapter, RecyclerView.LayoutManager manager){
    recyclerView.setLayoutManager(manager);
    recyclerView.setAdapter(adapter);
}

当设置requireAll为false时,说明在xml文件中不是必须两个参数都要设置。

  • @BindingConversion

这个注解主要是对属性类型的转换

<View
	android:background="@{@color/red}"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"/>
@BindingConversion
public static ColorDrawable convertColorToDrawable(int color){
    return new ColorDrawable(color);
}

这样就会对@color/red进行类型转换,该方法也必须声明为 public static

发布了31 篇原创文章 · 获赞 9 · 访问量 1596

猜你喜欢

转载自blog.csdn.net/qq_43621019/article/details/104137277