recyclerview general adapter of mvvm mode

Posted by Ghostgator on Mon, 16 Dec 2019 20:05:35 +0100

Recently, I plan to refactor the project. I plan to use mvvm mode. I try to write a general adapter for recyclerview in mvvm mode. It's refreshing and pleasant to use


package demo.xinchuang.com.mvvmdemo;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * RecyclerView Universal Adapter
 * <p>
 * Created by suwenlai on 16-12-27.
 */

public class MvvmCommonAdapter extends RecyclerView.Adapter<MvvmCommonAdapter.CommonHolder> {

    protected Context mContext;
    //Data set of all item s
    protected List mDatas;
    //item layout file id
    protected int mLayoutId;
    protected LayoutInflater mInflater;
    // viewModel reference of mvvm binding
    private int mVariableId;

    //Construction method
    public MvvmCommonAdapter(List datas, int variableId, Context context, int layoutId) {
        mContext = context;
        mDatas = datas;
        mLayoutId = layoutId;
        mInflater = LayoutInflater.from(mContext);
        mVariableId = variableId;
    }


    public List getmDatas() {
        return mDatas;
    }

    public void setmDatas(List mDatas) {
        this.mDatas = mDatas;
    }

    @Override
    public CommonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), mLayoutId, parent, false);
        CommonHolder myHolder = new CommonHolder(binding.getRoot());
        myHolder.setBinding(binding);
        return myHolder;
    }

    @Override
    public void onBindViewHolder(CommonHolder holder, int position) {
        holder.binding.setVariable(mVariableId,mDatas.get(position));
        holder.binding.executePendingBindings();
    }


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


    class CommonHolder extends RecyclerView.ViewHolder {
        private ViewDataBinding binding;

        public CommonHolder(View itemView) {
            super(itemView);
        }

        public ViewDataBinding getBinding() {
            return binding;
        }

        public void setBinding(ViewDataBinding binding) {
            this.binding = binding;
        }
    }
}

Easy to use

list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
list.setAdapter(new MvvmCommonAdapter(mData,BR.myUser,this,R.layout.second_adapter));

Just now, a comment asked what BR is. BR is a class generated in the compilation phase. Its function is similar to R.java

Because if the data in myUser is changed, the space cannot be updated synchronously

So here, myUser inherits BaseObservable, marks getter method with @ Bindable, and generates the field ID in BR
Then add notifyPropertyChanged(BR.field) to the set method;

Manual notification is still required when data changes. Call notifyPropertyChanged(BR.field) to inform the system that the data of BR.field has changed and the view needs to be updated

public class myUser extends BaseObservable {

    private String nickName;
    private String userface;
    private String userName;
    private String age;

    public User(String nickName, String userface, String userName, String age) {
        this.nickName = nickName;
        this.userface = userface;
        this.userName = userName;
        this.age = age;
    }

    public User() {
    }

    @Bindable
    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
        notifyPropertyChanged(BR.nickName);
    }

    @Bindable
    public String getUserface() {
        return userface;
    }

    public void setUserface(String userface) {
        this.userface = userface;
        notifyPropertyChanged(BR.userface);
    }

    @Bindable
    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
        notifyPropertyChanged(BR.age);
    }
    

    @Bindable
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
        notifyPropertyChanged(BR.userName);
    }
}

Another way is through observablefield

public class PlainUser {
    public final ObservableField<String> firstName = new ObservableField<>();
    public final ObservableField<String> nickName= new ObservableField<>();
    public final ObservableInt age = new ObservableInt();
}

The specific use method can be Baidu

xml file

<?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>
        <variable
            name="myUser"
            type="demo.xinchuang.com.mvvmdemo.UserEntity"/>
    </data>

    <LinearLayout
        android:onClick="@{myUser.onItemClick}"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            app:imageUrl="@{myUser.userface}"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content" />

        <TextView
            android:text="@{myUser.nickName}"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:layout_width="0dp"
            android:text="@{myUser.userName}"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <TextView
            android:layout_width="0dp"
            android:text="@{String.valueOf(myUser.age)}"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>
</layout>

Change from: https://blog.csdn.net/suwenlai/article/details/74456664

Topics: Android Java xml encoding