5

I added a selector background for my RecyclerView items, but I need to allow only single item selection at a time. i.e if one item is selected all the rest of the items must not be selected. How can I achieve this?

Here is my adapter class

public class VisaTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    Context context;
    private List<VisaType> visaTypeList;

    int selected_position;


    public VisaTypeAdapter(Context context, List<VisaType> visaTypeList) {
        this.context = context;
        this.visaTypeList = visaTypeList;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.visa_type_row, parent, false);
        return new jp.workjapan.adapters.VisaTypeAdapter.ViewHolder(view);

    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        final VisaType a = visaTypeList.get(position);
        final jp.workjapan.adapters.VisaTypeAdapter.ViewHolder viewHolder = (jp.workjapan.adapters.VisaTypeAdapter.ViewHolder) holder;
        viewHolder.visa_eng.setText(a.getName_en());
        viewHolder.visa_jp.setText(a.getName_jp());


        final long id = a.getId();
        if (id == AppSingleTon.visaType) {
            viewHolder.visa_layout.setSelected(true);
        } else {
            viewHolder.visa_layout.setSelected(false);
        }


        viewHolder.visa_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (viewHolder.visa_layout.isSelected()) {
                    viewHolder.visa_layout.setSelected(false);


                } else {

                    viewHolder.visa_layout.setSelected(true);
                    AppSingleTon.visaType = id;
                    selected_position = position;


                }


            }
        });

    }

}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
ANDROID_ROOKIE
  • 53
  • 1
  • 1
  • 4
  • Are you showing this recyclerview inside an AlertDialog? If yes, you should use an `ArrayAdapter` with the layout `android.R.layout.select_dialog_singlechoice`. – Jay Dec 18 '17 at 07:48
  • Possible duplicate of [Single selection in RecyclerView](https://stackoverflow.com/questions/28972049/single-selection-in-recyclerview) – Muhammad Saad Dec 18 '17 at 07:49

2 Answers2

8

This is my sample solution:

public class VisaTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    Context context;
    private List<VisaType> visaTypeList;

    int selected_position;


    public VisaTypeAdapter(Context context, List<VisaType> visaTypeList) {
        this.context = context;
        this.visaTypeList = visaTypeList;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.visa_type_row, parent, false);
        return new jp.workjapan.adapters.VisaTypeAdapter.ViewHolder(view);

    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        final VisaType a = visaTypeList.get(position);
        final jp.workjapan.adapters.VisaTypeAdapter.ViewHolder viewHolder = (jp.workjapan.adapters.VisaTypeAdapter.ViewHolder) holder;
        viewHolder.visa_eng.setText(a.getName_en());
        viewHolder.visa_jp.setText(a.getName_jp());


        final long id = a.getId();
        if (id == AppSingleTon.visaType) {
            viewHolder.visa_layout.setSelected(true);
        } else {
            viewHolder.visa_layout.setSelected(false);
        }

        if (position == selected_position) {
            viewHolder.visa_layout.setSelected(true);
        } else {
            viewHolder.visa_layout.setSelected(false);
        }

        viewHolder.visa_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selected_position = getAdapterPosition();
                notifyDataSetChanged();
            }
        });

    }

}

Hope it helps you... Thanks

Sijan
  • 104
  • 1
2

You can also consider usage of RecyclerView extended by SelectionTracker. Then some piece of code must be added to your current implementation to implement all needed methods. Finally in a place where you build SelectionTracker you can put code like below and inject SelectionTracker into your Adapter class.

Exapmle code of constructing SelectionTracker:

SelectionTracker selectionTracker = new SelectionTracker.Builder<>(
        "example-unique-id",
        mRecyclerView,
        new UsersListAdapter.UserItemKeyProvider(list),
        new UsersListAdapter.UserItemLookup(mRecyclerView),
        StorageStrategy.createStringStorage()
    ).withSelectionPredicate(SelectionPredicates.<String>createSelectSingleAnything()).build();

Method:

withSelectionPredicate(SelectionPredicates.<String>createSelectSingleAnything())

is the crucial here because it defines "selection approach". String here is one of possible keys. For more information follow:

  1. Official guide about RecyclerView: https://developer.android.com/guide/topics/ui/layout/recyclerview
  2. Dev documentation: https://developer.android.com/reference/androidx/recyclerview/selection/SelectionPredicates
Antares
  • 518
  • 6
  • 11