如何在 RecyclerView 中实现多选? [英] How to implement multi-select in RecyclerView?

查看:63
本文介绍了如何在 RecyclerView 中实现多选?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现具有多个可选项目的 RecyclerView.

解决方案

我知道现在回答这个问题有点晚了.而且我不知道它是否符合OP的要求.但这可能对某人有所帮助.我用一个简单的技巧实现了这个多选 RecyclerView.这是我的代码.

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android";xmlns:app="http://schemas.android.com/apk/res-auto";android:layout_width=match_parent"android:layout_height=match_parent"android:background="#EEE"><android.support.v7.widget.RecyclerViewandroid:id="@+id/recycler_view";android:layout_width=match_parent"android:layout_height=match_parent"/></RelativeLayout>

item_row.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";xmlns:tools="http://schemas.android.com/tools"android:layout_width=match_parent"android:layout_height="wrap_content";android:layout_marginBottom=1dp"机器人:背景=#FFF";android:clickable="true"机器人:方向=垂直"><文本视图android:id="@+id/text_view";android:layout_width=match_parent"android:layout_height="wrap_content";android:padding="10dp"工具:文本=TextView"/></LinearLayout>

item_row.xml android:clickable="true" 中很重要.

MainActivity.java

公共类 MainActivity 扩展 AppCompatActivity {私人列表<型号>mModelList;私有 RecyclerView mRecyclerView;私有 RecyclerView.Adapter mAdapter;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);mAdapter = new RecyclerViewAdapter(getListData());LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);mRecyclerView.setHasFixedSize(true);mRecyclerView.setLayoutManager(manager);mRecyclerView.setAdapter(mAdapter);}私人列表<型号>获取列表数据(){mModelList = new ArrayList<>();for (int i = 1; i <= 25; i++) {mModelList.add(new Model("TextView" + i));}返回 mModelList;}}

Model.java

公共类模型{私人字符串文本;私有布尔值 isSelected = false;公共模型(字符串文本){this.text = 文字;}公共字符串 getText() {返回文本;}公共无效集选择(布尔选择){isSelected = 被选中;}公共布尔 isSelected() {返回被选中;}}

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter{私人列表<型号>mModelList;公共 RecyclerViewAdapter(ListmodelList) {mModelList = 模型列表;}@覆盖public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {查看视图 = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);返回新的 MyViewHolder(view);}@覆盖公共无效 onBindViewHolder(最终 MyViewHolder 持有人,int 位置){最终模型模型 = mModelList.get(position);holder.textView.setText(model.getText());holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);holder.textView.setOnClickListener(new View.OnClickListener() {@覆盖公共无效onClick(查看视图){model.setSelected(!model.isSelected());holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);}});}@覆盖公共 int getItemCount() {返回 mModelList == null ?0 : mModelList.size();}公共类 MyViewHolder 扩展 RecyclerView.ViewHolder {私人视图;私有文本视图文本视图;私人 MyViewHolder(查看 itemView){超级(项目视图);视图 = 项目视图;textView = (TextView) itemView.findViewById(R.id.text_view);}}}

它是如何工作的?onBindViewHolder() 方法将 ArrayList 中的数据绑定到 View 对象.因此,及时将数据绑定到视图,它从 ArrayList 获取单个对象,即 Model model = mModelList.get(position); 与当前位置.现在我们需要检查是否选择了该特定对象.像这样,

model.isSelected()

返回 truefalse.如果该对象已被选中,我们需要更改所选 row_item 的背景颜色.为此,这里是代码

holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);

如果它被选中,将背景颜色更改为cyan else white.

对于选择,我们需要使用 setOnClickListener() 方法.(这里我只使用了一个 TextView.所以我在 TextView 上执行一个点击事件).这里holder.view 表示整个单个item_row.Onclick 将布尔值切换为 truefalse.

 holder.textView.setOnClickListener(new View.OnClickListener() {@覆盖公共无效onClick(查看视图){model.setSelected(!model.isSelected());holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);}});

在托管 RecyclerView 的 Activity 或 Fragment 中,您可以像这样获取选定的对象/项目

String text = "";对于(模型模型:mModelList){如果(模型.isSelected()){text += model.getText();}}Log.d("TAG","输出:"+文本);

这是输出

编辑 1: 限制用户只能选择一项.

 private int lastSelectedPosition = -1;//声明这个变量...//你的代码...@覆盖公共无效 onBindViewHolder(最终 MyViewHolder 持有人,int 位置){最终模型模型 = mModelList.get(position);holder.textView.setText(model.getText());holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);holder.textView.setOnClickListener(new View.OnClickListener() {@覆盖公共无效onClick(查看视图){//检查你是否选择了一个项目if(lastSelectedPosition > 0) {mModelList.get(lastSelectedPosition).setSelected(false);}model.setSelected(!model.isSelected());holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);//存储最后选择的项目位置lastSelectedPosition = holder.getAdapterPosition();}});}

希望对您有所帮助.

I'm trying to implement a RecyclerView with multiple selectable items.

Here is what I've tried but I couldn't make it work.

This is what I'm trying to do:

解决方案

I know it's a little bit late to answer this question. And I don't know whether it meets requirements of OP or not. But this may help someone. I implemented this multi-select RecyclerView with a simple trick. Here is my code.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EEE">

   <android.support.v7.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</RelativeLayout>

item_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="1dp"
    android:background="#FFF"
    android:clickable="true" 
    android:orientation="vertical">

   <TextView
      android:id="@+id/text_view"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:padding="10dp"
      tools:text="TextView" />

</LinearLayout>

In item_row.xml android:clickable="true" is important.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private List<Model> mModelList;
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mAdapter = new RecyclerViewAdapter(getListData());
        LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setAdapter(mAdapter);
    }

    private List<Model> getListData() {
      mModelList = new ArrayList<>();
      for (int i = 1; i <= 25; i++) {
          mModelList.add(new Model("TextView " + i));
      }
     return mModelList;
    }
}

Model.java

public class Model {

    private String text;
    private boolean isSelected = false;

    public Model(String text) {
      this.text = text;
    }

    public String getText() {
      return text;
    }

    public void setSelected(boolean selected) {
      isSelected = selected;
    }


    public boolean isSelected() {
      return isSelected;
    }
}

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {

    private List<Model> mModelList;

    public RecyclerViewAdapter(List<Model> modelList) {
      mModelList = modelList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
       View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
       return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        final Model model = mModelList.get(position);
        holder.textView.setText(model.getText());
        holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                model.setSelected(!model.isSelected());
                holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
            }
        });
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder {

        private View view;
        private TextView textView;

        private MyViewHolder(View itemView) {
            super(itemView);
            view = itemView;
            textView = (TextView) itemView.findViewById(R.id.text_view);
        }
    }
}

How does it work? onBindViewHolder() method binds the data from ArrayList to View objects. So, on time binding the data to the view it gets the single object from ArrayList that is Model model = mModelList.get(position); with the current position. Now we need to check whether that particular object is selected or not. Like this,

model.isSelected()

which returns either true or false. If that object is already selected we need to change the background color of row_item selected. For this here is the code

holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);

If it's selected change the background color to cyan else white.

For selection we need to use setOnClickListener() method. (here I am using only a TextView. So I am performing a click event on TextView). Here holder.view means the entire single item_row. Onclick toggle the boolean values to true or false.

 holder.textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            model.setSelected(!model.isSelected());
            holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
        }
 });

In your Activity or Fragment which is hosting RecyclerView, you can get the selected objects/items like this

String text = "";
 for (Model model : mModelList) {
   if (model.isSelected()) {
     text += model.getText();
   }
 }
Log.d("TAG","Output : " + text);

Here is the output

Edit 1: Restricting user to select only one item.

 private int lastSelectedPosition = -1;  // declare this variable
 ...
 // your code
 ...

 
 @Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
    final Model model = mModelList.get(position);
    holder.textView.setText(model.getText());
    holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
    holder.textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // check whether you selected an item
            
            if(lastSelectedPosition > 0) {
                mModelList.get(lastSelectedPosition).setSelected(false);
            }

            model.setSelected(!model.isSelected());
            holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);

            // store last selected item position 

            lastSelectedPosition = holder.getAdapterPosition();  
        }
    });
}

I hope it will be helpful.

这篇关于如何在 RecyclerView 中实现多选?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆