关于Android的Databinding在RecyclerView上使用的记录

       首先我是 不太喜欢Databinding这玩意的,虽然用着还是蛮爽的,一绑定所有的控件直接拿到,也不用findViewbyid了,但是这东西出错误了巨难差。你要是在xml里面写错了,AndroidStudio不报错的那种错误,那你就头疼吧。Databinding对象死活就不会生成,纠结到死。 算了,不吐槽了,说不上AndroidStudio以后会对Databinding支持的特别好 也说不好。

       废话不多说。这里记录一下在RecyclerView中使用Databinding,在多布局的时候简化布局那还是挺爽的。Databinding的配置自己搞,网上一查一大堆。我默认你们都配置好了Databinding和Glide了。

完成样式:

关于Android的Databinding在RecyclerView上使用的记录

 第一步,我们先创建最基本的MainActivity和它的layout, 这里主activity的layout用Databing纯属是我偷懒不想写findViewById。哈哈哈

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static MessageAdapter adapter = null;
    private static RecyclerView recyclerView = null;
    private static ActivityMainBinding binding = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.addTextItem.setOnClickListener(this);
        binding.addImageItem.setOnClickListener(this);
        recyclerView = binding.recyclerview;

        adapter = new MessageAdapter(this,initData());
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }

    //这里初始化一组数据
    public List<BaseMessage> initData(){
        List<BaseMessage> list = new ArrayList<>();
        list.add(new TextMessageBean("新消息一"));
        list.add(new TextMessageBean("新消息二"));
        list.add(new TextMessageBean("新消息三"));
        list.add(new TextMessageBean("新消息四"));
        list.add(new ImageMessageBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542465393611&di=677e365a4eb62a29278aef1d5d48fa40&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201411%2F11%2F20141111171817_8chGL.jpeg"));
        list.add(new TextMessageBean("新消息五"));
        list.add(new TextMessageBean("新消息六"));
        return list;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.add_text_item:
                adapter.updateItem(new TextMessageBean("新消息到了~"));

                break;
            case R.id.add_image_item:
                adapter.updateItem(new ImageMessageBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542468020668&di=43a1083a4d0ae308f90403b34463ec8a&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201605%2F10%2F20160510170018_sKmZe.thumb.700_0.png"));
                break;
        }
        //这个是每次都滚动到最后一行
        recyclerView.scrollToPosition(adapter.getItemCount()-1);
    }

}

 

<?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>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        </android.support.v7.widget.RecyclerView>

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

            <Button
                android:id="@+id/add_text_item"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="增加文字消息" />

            <Button
                android:id="@+id/add_image_item"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="增加图片消息" />
        </LinearLayout>

    </LinearLayout>
</layout>

第二步,我们创建一个BaseMessage的接口,让两个数据JavaBean都继承它,分别存放文字类型和图片类型,这玩意后期自己还能拓展拓展啥的。

BaseMessage

public interface BaseMessage {
    final int TextMessage = 0;
    final int ImageMessage = 1;
    int getType();
}

TextMessageBean

public class TextMessageBean extends BaseObservable implements BaseMessage{
    String msgTime = "";
    String content = "";

    public TextMessageBean(String message){
        setContent(message);
    }

    public String getMsgTime() {
        return msgTime;
    }

    public void setMsgTime(String msgTime) {
        this.msgTime = msgTime;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public int getType() {
        return BaseMessage.TextMessage;
    }
}

 ImageMessageBean(这里面注意特殊写了一个方法让glide处理传入URL设置图片)

public class ImageMessageBean implements BaseMessage{
    String imageURL = "";

    public ImageMessageBean(String url){
        setImageURL(url);
    }

    public String getImageURL() {
        return imageURL;
    }

    public void setImageURL(String imageURL) {
        this.imageURL = imageURL;
    }

    @Override
    public int getType() {
        return BaseMessage.ImageMessage;
    }

    //这里写了一个static方法,用于特殊处理传入的图片
    //第一个参数是默认的绑定数据类型是什么就会传入
    //第二个参数是设定的参数
    @BindingAdapter({"loadImage"})
    public static void loadImage(ImageView imageView,String url){
        Glide.with(imageView).load(url).into(imageView);
    }


}

第三步,写这个通用的Adapter方法。(Recycler使用就不科普了,来看的都会用 )

public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<BaseMessage> list = null;
    private Context context = null;

    public MessageAdapter(Context cont,List<BaseMessage> li){
        this.list = li;
        this.context = cont;
    }
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        ViewDataBinding binding = null;
        switch (viewType){
            case BaseMessage.TextMessage:
                binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.recycler_msg_item,viewGroup,false);
                break;
            case BaseMessage.ImageMessage:
                binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.recycler_img_item,viewGroup,false);
                break;
        }
        return new MyViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {

        ((MyViewHolder)viewHolder).getBinding().setVariable(BR.data,list.get(position));
        ((MyViewHolder)viewHolder).getBinding().executePendingBindings();
    }

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

    @Override
    public int getItemViewType(int position) {
        return list.get(position).getType();
    }

    public void updateItem(BaseMessage message){
        list.add(message);
        notifyDataSetChanged();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        ViewDataBinding binding = null;
        public MyViewHolder(ViewDataBinding itemView) {
            super(itemView.getRoot());
            this.binding = itemView;
        }

        public ViewDataBinding getBinding(){
            return binding;
        }
    }

}

这里最方便的就是,多种数据类型你只需要写一个ViewHolder,写一个onBindViewHolder就可以处理了。你只需要在onCreateBindView中判断一下数据类型构造不同的view就可以了。很屌很溜