web-dev-qa-db-fra.com

Comment implémenter la multi-sélection dans RecyclerView?

This is implemented using ListView

ListView avait un mode à choix multiples, que dois-je utiliser pour implémenter le même en utilisant RecyclerView? Comment gérer onItemCheckedStateChanged? J'ai vérifié ceci , mais je ne pouvais pas en tirer grand chose. Un extrait de code ou un exemple de projet mettant en œuvre le même serait formidable. Merci d'avance.

49
Hegdekar

Je sais qu'il est un peu tard pour répondre à cette question. Et je ne sais pas si cela répond aux exigences de l'OP ou non. Mais cela peut aider quelqu'un. J'ai implémenté ce RectyclerView à sélections multiples avec un truc simple. Voici mon 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>

Dans item_row.xmlAndroid:clickable="true" Est 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);
        }
    }
}

Comment ça marche? La méthode onBindViewHolder() lie les données d'ArrayList aux objets View. Ainsi, au moment de lier les données à la vue, l'objet unique obtenu de ArrayList est Model model = mModelList.get(position); avec la position actuelle. Nous devons maintenant vérifier si cet objet est sélectionné ou non. Comme ça,

model.isSelected()

qui retourne soit true ou false. Si cet objet est déjà sélectionné, nous devons modifier la couleur d'arrière-plan de row_item Sélectionné. Pour cela voici le code

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

Si cette option est sélectionnée, changez la couleur d'arrière-plan en cyan sinon white.

Pour la sélection, nous devons utiliser la méthode setOnClickListener(). (ici, je n'utilise que TextView. Je réalise donc un événement de clic sur TextView). Ici holder.view Signifie le single entier item_row. Onclick bascule les valeurs booléennes sur true ou 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);
        }
 });

Dans votre activité ou fragment hébergeant RecyclerView, vous pouvez obtenir les objets/éléments sélectionnés comme ceci

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

Voici la sortie

output

Éditer 1: Restreindre l'utilisateur pour ne sélectionner qu'un seul élément.

 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();  
        }
    });
}

J'espère que cela vous sera utile.

90
Shashanth

La création de l'implémentation personnalisée multi-sélections mentionnée fonctionne correctement, mais peut entraîner des problèmes de performances lorsque l'ensemble de données est énorme. Je vous recommande vivement de lire la section "Création de la vue Recyclage - Activer la sélection d’éléments de liste" par Google. J'ai répertorié le lien Documentation Android pour la création d'une vue de recyclage, cliquez sur un élément d'activation

6
Farruh Habibullaev
public class RecyclerColorAdapter extends RecyclerView.Adapter<RecyclerColorAdapter.ViewHolder> {


        private final Activity activity;
        private final ArrayList<ColorItem> itemArrayList;


        public RecyclerColorAdapter(Activity activity, ArrayList<ColorItem> itemArrayList) {
            super();
            this.activity = activity;
            this.itemArrayList = itemArrayList;
        }


        @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_color_recycleview, viewGroup, false);
            return new ViewHolder(v);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int i) {
            holder.setIsRecyclable(true);

            final ColorItem colorItem = itemArrayList.get(i);


            holder.button_color.setText(colorItem.getColorName());

            holder.button_color.setBackgroundColor(colorItem.isSelected() ? Color.CYAN : Color.WHITE);

            holder.button_color.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    colorItem.setSelected(!colorItem.isSelected());
                    holder.button_color.setBackgroundColor(colorItem.isSelected() ? Color.CYAN : Color.WHITE);
                    if (colorItem.isSelected()){
                        arrayListColor.add("diamond_color[]="+colorItem.getValue()+"&");
                        Log.e("arrayListColor","---------"+arrayListColor);
                    }
                    else {
                        arrayListColor.remove("diamond_color[]="+colorItem.getValue()+"&");
                        Log.e("arrayListColor","---------"+arrayListColor);
                    }


                }
            });

        }

        @Override
        public int getItemCount() {

            return itemArrayList.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

            private Button button_color;

            public ViewHolder(View itemView) {
                super(itemView);
                itemView.setOnClickListener(this);
                button_color = (Button) itemView.findViewById(R.id.button_color);

            }

            @Override
            public void onClick(View v) {

            }

        }

    }
2
Pradip

Sans créer de classe de modèle, nous pouvons sélectionner plusieurs éléments dans Recyclerview. utiliser ce code dans l'adaptateur recyclerview

holder.favplayIcon.setOnClickListener(View.OnClickListener {
                    if (!row_index.contains(position)) {
                        row_index.add(position)
                        holder.favplayIcon.setImageDrawable(
                            ResourcesCompat.getDrawable(resources, R.drawable.ic_starfilled, null ))

                    } else {
                        row_index.removeAt(row_index.indexOf(position))
                        holder.favplayIcon.setImageDrawable(
                   ResourcesCompat.getDrawable(resources,R.drawable.ic_starborder, null)
                        )  }
                })

///// put below code out of onclicklistener method of item
                if (!row_index.contains(position)) {

                    holder.favplayIcon.setImageDrawable(
                        ResourcesCompat.getDrawable(
                            resources,
                            R.drawable.ic_starborder,
                            null
                        )
                    )
} else {
                    holder.favplayIcon.setImageDrawable(
                        ResourcesCompat.getDrawable(
                            resources,
                            R.drawable.ic_starfilled,
                            null
                        )
                    )
1
civani mahida

Manière simple et courte de le faire:

  holder.parentLayout.setOnClickListener {

        if (holder.categoryIcon.isSelected) {
            selectedPos = position
        }

        if (selectedPos == position) {
            notifyItemChanged(selectedPos)
            selectedPos = RecyclerView.NO_POSITION
        } else {
            selectedPos = position
            notifyItemChanged(selectedPos)
        }
    }


    if (selectedPos == position) {
        holder.categoryIcon.setBackgroundColor(ContextCompat.getColor(context, R.color.orange))
        holder.categoryIcon.isSelected = true
    } else {
        holder.categoryIcon.setBackgroundColor(ContextCompat.getColor(context, R.color.white))
        holder.categoryIcon.isSelected = false
    }
0
Aleesha Kanwal