Android - use of data binding RecyclerView

Keywords: Android encoding xml github

Today, let's talk about the use of DataBinding in the list RecyclerView

List binding

List display is often used in App. Data Binding plays an important role in the list, directly binding data and events to each list item.

 

RecyclerView

In the past, we used to use ListView, GridView, or some customized views on GitHub to do waterfall flow. Since the advent of RecyclerView, we have had a new choice, just using the LayoutManager.

RecyclerView's built-in garbage collection, ViewHolder and ItemDecoration mechanism allow us to replace the original ListView and GridView without hesitation.

 

Main layout:

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

    </data>

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

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

            <Button
                android:id="@+id/btn_demo8_add"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Add to" />

            <Button
                android:id="@+id/btn_demo8_refresh"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_weight="1"
                android:text="Refresh" />

            <Button
                android:id="@+id/btn_demo8_delete"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_weight="1"
                android:text="delete" />
        </LinearLayout>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/demo8_recyclerview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"></android.support.v7.widget.RecyclerView>
    </LinearLayout>

</layout>

item layout:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
   
        <import type="com.zhangqie.databinding.demo8.UserObservableBean"/>

        <variable
            name="userObserBean"
            type="UserObservableBean"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:descendantFocusability="blocksDescendants"
        android:orientation="horizontal">


        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:gravity="center"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{`Serial number:` + userObserBean.userId }" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{`Full name:` +userObserBean.userName}"
                android:layout_marginTop="5dp"
                />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:gravity="center"
            >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{`Age:` +userObserBean.userAge}"
                />

            <!--Be sure to use 1 f Instead of using 1, the type must correspond to-->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:text="@{`Gender:` + (userObserBean.userSex == 1f ? `male` : `female`)}" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_marginRight="10dp"
            android:paddingBottom="10dp"
            >

            <Button
                android:id="@+id/btn_update"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:text="Modifying data" />

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:text="Delete data" />
        </LinearLayout>
    </LinearLayout>
</layout>

ViewHolder

public class RecyclerViewHolder extends RecyclerView.ViewHolder {

    public Item8MvvmBinding getItem8MvvmBinding() {
        return item8MvvmBinding;
    }

    public void setItem8MvvmBinding(Item8MvvmBinding item8MvvmBinding) {
        this.item8MvvmBinding = item8MvvmBinding;
    }

    //Here, just return a view to RecyclerView.ViewHolder, so we will pass databinding into the constructor
    Item8MvvmBinding item8MvvmBinding;



    public RecyclerViewHolder(Item8MvvmBinding item8MvvmBinding) {
        super(item8MvvmBinding.getRoot());
        this.item8MvvmBinding = item8MvvmBinding;
    }
}

adapter:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolder> implements View.OnClickListener{


    private List<UserObservableBean> list;
    private Random random = new Random(System.currentTimeMillis());


    public RecyclerViewAdapter(List<UserObservableBean> list) {
        this.list = list;
    }

    public OnItemOnClickListener getOnItemOnClickListener() {
        return onItemOnClickListener;
    }

    public void setOnItemOnClickListener(OnItemOnClickListener onItemOnClickListener) {
        this.onItemOnClickListener = onItemOnClickListener;
    }

    private OnItemOnClickListener onItemOnClickListener;

    public interface OnItemOnClickListener{
        void onItemClick(View view, int position);
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Item8MvvmBinding item8MvvmBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item8_mvvm,parent,false);
        item8MvvmBinding.getRoot().setOnClickListener(this);
        return new RecyclerViewHolder(item8MvvmBinding);
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        Item8MvvmBinding item8MvvmBinding = holder.getItem8MvvmBinding();
        UserObservableBean userObservableBean = list.get(position);
        item8MvvmBinding.setVariable(com.zhangqie.databinding.BR.userObserBean,userObservableBean);
        //Save the position in the Tag of itemView, so as to get it when clicking
        item8MvvmBinding.getRoot().setTag(position);
        item8MvvmBinding.btnUpdate.setOnClickListener(new OnBtnClickListener(1, userObservableBean));
        item8MvvmBinding.btnDelete.setOnClickListener(new OnBtnClickListener(2, position));
        // Bind now
        item8MvvmBinding.executePendingBindings();
    }

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

    public void addData(UserObservableBean userObservableBean){
        int position = random.nextInt(list.size()+1);
        list.add(position,userObservableBean);
        notifyItemInserted(position);//Add animation for action
    }

    public void deleteData(int positionn){
        if (list.size() == 0){
            return;
        }
        int position = random.nextInt(list.size());
        list.remove(position);
        notifyItemRemoved(position);//Animation for delete operation
    }

    @Override
    public void onClick(View view) {
        if (onItemOnClickListener != null)
            onItemOnClickListener.onItemClick(view, (int) view.getTag());
    }

    private class OnBtnClickListener implements View.OnClickListener{

        private int stats;//1, modify; 2, delete
        private UserObservableBean userBean;
        private int position;

        OnBtnClickListener(int stats, UserObservableBean userBean) {
            this.stats = stats;
            this.userBean = userBean;
        }

        OnBtnClickListener(int stats, int position) {
            this.stats = stats;
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            switch (stats) {
                case 1:
                    userBean.userName.set("Modified name");
                    break;
                case 2:
                    list.remove(position);
                    notifyDataSetChanged();
                    break;
            }
        }
    }

}

Primary Activity:

public class Demo8 extends AppCompatActivity {

    Demo8Binding demo8Binding;
    RecyclerViewAdapter recyclerViewAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        demo8Binding = DataBindingUtil.setContentView(this, R.layout.demo8);
        initView();
    }

    private void initView(){
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        demo8Binding.demo8Recyclerview.setLayoutManager(layoutManager);
        recyclerViewAdapter = new RecyclerViewAdapter(initObservableData());
        demo8Binding.demo8Recyclerview.setAdapter(recyclerViewAdapter);

        //Click event of item
        recyclerViewAdapter.setOnItemOnClickListener(new RecyclerViewAdapter.OnItemOnClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(Demo8.this, "Row number:" + position, Toast.LENGTH_LONG).show();
            }
        });
       

        demo8Binding.btnDemo8Add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                UserObservableBean userBean = new UserObservableBean();
                userBean.userId.set(8);
                userBean.userName.set("Heart to heart"+8);
                userBean.userAge.set(25);
                userBean.userSex.set(8 % 2 == 0 ? 1 : 0);
                recyclerViewAdapter.addData(userBean);
            }
        });
        demo8Binding.btnDemo8Refresh.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              recyclerViewAdapter.notifyDataSetChanged();
            }
        });
        demo8Binding.btnDemo8Delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recyclerViewAdapter.deleteData(1);
            }
        });
    }


    //Initialize test data
    private List<UserObservableBean> initObservableData() {
        List<UserObservableBean> list = new ArrayList<>();
        for (int i = 1; i < 6; i++) {
            UserObservableBean userBean = new UserObservableBean();
            userBean.userId.set(i);
            userBean.userName.set("Heart to heart"+i);
            userBean.userAge.set(18 + i);
            userBean.userSex.set(i % 2 == 0 ? 1 : 0);
            list.add(userBean);
        }
        return list;
    }
}

A RecyclerView + Databinding application for self practice

 

The effect is as follows:

                  

Posted by tat on Tue, 24 Dec 2019 12:01:30 -0800