问题
Hello I am trying to implement multi select in recycler view
android for showing an icon when clicked on that particular view, I have tried the below code and is working fine for that particular position, however there are other several views that too are getting updated, so please check and let me know what am I missing
Here is my adapter code:
public class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
Context context;
ArrayList<String> alContactName, alContactEmail, alContactNumber;
ArrayList<Boolean> alFromLinkedIn;
int mergeFlag=0;
private static SparseBooleanArray selectedItems;
ArrayList<Integer> alSelectedPositions;
public ContactsAdapter(Context context, ArrayList<String> alContactName, ArrayList<String> alContactEmail, ArrayList<String> alContactNumber, ArrayList<Boolean> alisFromLinkedIn) {
//Include one more variable for checking type i.e linked in or normal contact
super();
this.context = context;
this.alContactName = alContactName;
this.alContactEmail = alContactEmail;
this.alContactNumber = alContactNumber;
this.alFromLinkedIn = alisFromLinkedIn;
alSelectedPositions=new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_merge_contact, parent, false);
return new ContactsHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
try {
((ContactsHolder) holder).relMain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alSelectedPositions.add(position);
notifyDataSetChanged();
}
});
if(alSelectedPositions.get(position)==position){
((ContactsHolder) holder).imgMerge.setVisibility(View.VISIBLE);
}
else {
((ContactsHolder) holder).imgMerge.setVisibility(View.GONE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
回答1:
check updated code. I have modified the @tahsinRupam code.
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
try {
((ContactsHolder) holder).relMain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(alSelectedPositions.size>0)
{
for(int i=0;i<a1SelectedPositions.size;i++)
{
//if you want to cleasr previous details of array
if(a1SelectedPositions.contains(position))
alSelectedPositions.remove(position);
else
alSelectedPositions.add(position);
}
}
else
{
alSelectedPositions.add(position);
notifyDataSetChanged();
}
});
//update the position on scroll
for(int i=0;i<a1SelectedPositions.size;i++)
{
if(alSelectedPositions.get(i)==position){
((ContactsHolder)holder).imgMerge.setVisibility(View.VISIBLE);
}
else {
((ContactsHolder) holder).imgMerge.setVisibility(View.GONE);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
回答2:
Recently I had to implement a multi select RecyclerView
, below I attached a simplified code snippet for a clean way to implement multi-select feature in RecyclerView
:
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemHolder> implements IMultiSelectableList<Item> {
boolean selectionMode = false;
HashSet<Item> selectedItems;
ArrayList<Item> mItems;
public ItemAdapter(ArrayList<Item> Items) {
super();
selectedItems = new HashSet<>();
mItems = Items;
}
public void enterSelectionModeWithItem(int selectedItemPosition){
if(selectedItemPosition >= 0 && selectedItemPosition < mItems.size())
selectedItems.add(mItems.get(selectedItemPosition));
selectionMode = true;
notifyDataSetChanged();
}
public void clearSelectionMode() {
selectionMode = false;
selectedItems.clear();
notifyDataSetChanged();
}
public class ItemHolder extends RecyclerView.ViewHolder{
ImageView mImage;
public ItemHolder(View itemView) {
super(itemView);
mImage = itemView.findViewById(R.id.image);
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if(!selectionMode){
int selectedPosition = getAdapterPosition();
Item selectedItem = mItems.get(selectedPosition);
enterSelectionModeWithItem(selectedItem);
return true;
}
return false;
}
});
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int selectedPosition = getAdapterPosition();
Item selectedItem = mItems.get(selectedPosition);
//Capture Clicks in Selection Mode
if(selectionMode){
if(selectedItems.contains(selectedItem)){
selectedItems.remove(selectedItem);
mImage.setImageResource(R.drawable.ic_checkbox_blank_circle_outline_grey600_48dp);
} else {
selectedItems.add(selectedItem);
mImage.setImageResource(R.drawable.ic_checkbox_marked_circle_grey600_48dp);
}
}
}
});
}
public void setupView(Item item){
if(selectionMode){
if(selectedItems.contains(item)){
mImage.setImageResource(R.drawable.ic_checkbox_marked_circle_grey600_48dp);
} else {
mImage.setImageResource(R.drawable.ic_checkbox_blank_circle_outline_grey600_48dp);
}
}
}
@Override
public ItemAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_item, parent, false);
return new ItemHolder(view);
}
@Override
public void onBindViewHolder(ItemAdapter.ItemHolder holder, int position) {
holder.setupView(mItems.get(position));
}
@Override
public int getItemCount() {
return mItems != null ? mItems.size() : 0;
}
}
, I use an image to show selection like Gmail app but feel free to use whatever works for you (background color, font style, etc).
P.S: I designed a callback interface for a simple selection interactions, if it helps I can attach it too! Cheers!
回答3:
You've to do some specific things:
Initialize an int type array (type can be different) and assign 0 value to all it's elements.
int[] selectedPos = null; public ContactsAdapter(Context context, ArrayList<String> alContactName, ArrayList<String> alContactEmail, ArrayList<String> alContactNumber, ArrayList<Boolean> alisFromLinkedIn) { //Include one more variable for checking type i.e linked in or normal contact super(); this.context = context; this.alContactName = alContactName; this.alContactEmail = alContactEmail; this.alContactNumber = alContactNumber; this.alFromLinkedIn = alisFromLinkedIn; alSelectedPositions=new ArrayList<>(); for(int i = 0 ; i < alContactName.size() ; i++) selectedPos[i] = 0; }
Store the selected positions in
selectedPos
.Then, check if the position is selected and set visibility accordingly:
In onBindViewHolder()
add the following code:
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
try {
((ContactsHolder) holder).relMain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
selectedPos[position] = 1;
notifyDataSetChanged();
}
});
} catch (Exception e) {
e.printStackTrace();
}
// Checking if the position was selected
if(selectedPos[position] == 1)
((ContactsHolder) holder).imgMerge.setVisibility(View.VISIBLE);
else
((ContactsHolder) holder).imgMerge.setVisibility(View.GONE);
}
回答4:
I have resolved my issue here is the code if it could help someone:
@Override
public ContactsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_merge_contact, parent, false);
final ContactsHolder holder = new ContactsHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (holder.getAdapterPosition() != RecyclerView.NO_POSITION) {
mSelectedItemPosition = holder.getAdapterPosition();
//notifyItemChanged(holder.getAdapterPosition());
notifyDataSetChanged();
}
}
});
return holder;
}
@Override
public void onBindViewHolder(ContactsHolder holder, int position) {
try {
if (mSelectedItemPosition == position) {
if (mergeFlag != 1) {
holder.imgMerge.setVisibility(View.VISIBLE);
mergeFlag = 1;
selectdParentId = contactsModels.get(position).alContactIdList;
} else{
//holder.relDone.setVisibility(View.GONE);
if (!selectdParentId.equals(contactsModels.get(position).alContactIdList)) {
holder.relDone.setVisibility(View.VISIBLE);
alChildId.add(contactsModels.get(position).alContactIdList);
} else {
holder.imgMerge.setVisibility(View.VISIBLE);
}
}
} else {
holder.imgMerge.setVisibility(View.GONE);
holder.relDone.setVisibility(View.GONE);
}
}
来源:https://stackoverflow.com/questions/49995229/multi-selection-in-recyclerview