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: