Disable checkbox in RecyclerView

1

Each item of a RecyclerView contains a Checkbox , and when selecting a checkbox you would like to disable all other checkboxes.

I created setOnCheckedChangeListener inside onBindViewHolder and I believe I should disable the other checkboxes inside it after a checkbox is selected, making a for and ignoring the selected one. But I do not know how to get every item in the RecyclerView and disable the checkbox.

Am I on the right track or should I implement it differently? Is there any simple way to do this?

Summarizing my scenario, I have a list and want the user to select only one item, disabling others after a selected one.

UPDATED:

ViewHolder:

public class LocalRouteSelectionViewHolder extends RecyclerView.ViewHolder {

    public final TextView tvId;
    public final TextView tvDate;
    public final TextView tvTarget;
    public final TextView tvAmount;
    public final CheckBox cbRouteSelect;

    public LocalRouteSelectionViewHolder(View view) {
        super(view);
        tvId = (TextView) view.findViewById(R.id.textview_route_selection_id);
        tvDate = (TextView) view.findViewById(R.id.textview_route_selection_date);
        tvTarget = (TextView) view.findViewById(R.id.textview_route_selection_target);
        tvAmount = (TextView) view.findViewById(R.id.textview_route_selection_amount);
        cbRouteSelect = (CheckBox) view.findViewById(R.id.checkbox_route_select);
    }

}

Adapter:

public class LocalRouteListSelectionAdapter extends RecyclerView.Adapter {

    private List<Route> routes;
    private Context context;
    Route route;

    public LocalRouteListSelectionAdapter(List<Route> routes, Context context) {
        this.routes = routes;
        this.context = context;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context)
                .inflate(R.layout.item_localroute_selection, parent, false);

        LocalRouteSelectionViewHolder holder = new LocalRouteSelectionViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
        LocalRouteSelectionViewHolder holder = (LocalRouteSelectionViewHolder) viewHolder;
        route = routes.get(position) ;

        String year = route.getDate().substring(0,4);
        String month = route.getDate().substring(5, 7);
        String day = route.getDate().substring(8, 10);
        String date = day + "/" + month + "/" + year;

        holder.tvId.setText(String.format("%03d", route.getId()));
        holder.tvDate.setText(date);
        holder.tvTarget.setText(route.getTarget());
        holder.tvAmount.setText(String.valueOf(route.getAmount()));

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Route route = routes.get(position);
                Context context = view.getContext();
                Intent intent = new Intent(context, RouteDetailsActivity.class);
                intent.putExtra("ROUTE", route);
                context.startActivity(intent);
            }
        });

        holder.cbRouteSelect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                // implementar aqui
            }
        });
    }

    @Override
    public int getItemCount() {
        return routes.size();
    }

}
    
asked by anonymous 29.08.2017 / 17:06

1 answer

1

I did something similar on a project of mine using Radio Button, which I believe is also the most appropriate for your case (checkboxes imply more than one selection). I'll put the code of my adapter:

public class SingleHistoryConfigureAdapter extends
        RecyclerView.Adapter<SingleHistoryConfigureAdapter.HistoryConfigWidgetViewHolder> {

    final private OnItemClickListener mOnClickListener;

    private Cursor mCursor;
    private Context mContext;
    private static int sItemSelected = -1;
    public static final int INVALID_HISTORY_ID = -1;

    public interface OnItemClickListener {
        void onListItemClick(long historyId);
    }

    public SingleHistoryConfigureAdapter(@NonNull Context context, OnItemClickListener listener) {
        mContext = context;
        mOnClickListener = listener;
    }

    public void swapCursor(Cursor newCursor) {
        mCursor = newCursor;
        notifyDataSetChanged();
    }

    public void invalidateSelection() {
        sItemSelected = -1;
    }

    public long getSelectedHistoryId() {
        return (mCursor != null && mCursor.moveToPosition(sItemSelected))
                ? mCursor.getLong(HistoryGridFragment.INDEX_HISTORY_ID)
                : INVALID_HISTORY_ID;
    }

    @Override
    public HistoryConfigWidgetViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        int layoutIdForListItem = R.layout.single_history_widget_item;
        LayoutInflater inflater = LayoutInflater.from(mContext);

        View view = inflater.inflate(layoutIdForListItem, viewGroup, false);
        return new HistoryConfigWidgetViewHolder(view);
    }

    @Override
    public void onBindViewHolder(HistoryConfigWidgetViewHolder holder, int position) {
        mCursor.moveToPosition(position);
        String title = Jsoup.parse(mCursor.getString(HistoryGridFragment.INDEX_HISTORY_TITLE)).text();
        holder.historyRadio.setText(title);
        holder.historyRadio.setChecked(sItemSelected == position);
    }

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

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

        public RadioButton historyRadio;

        public HistoryConfigWidgetViewHolder(View itemView) {
            super(itemView);
            historyRadio = (RadioButton) itemView.findViewById(R.id.option_radio);
            itemView.setOnClickListener(this);
            historyRadio.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            mCursor.moveToPosition(getAdapterPosition());
            mOnClickListener.onListItemClick(mCursor.getLong(HistoryGridFragment.INDEX_HISTORY_ID));

            sItemSelected = getAdapterPosition();
            notifyItemRangeChanged(0, getItemCount());
        }
    }
}

Quick explanation:

1) The selected item I chose to save in a static variable ( sItemSelected ) to persist in case of destruction of the Activity

2) The above variable is set to onClick() of the Radio (according to the position of the adapter), where I also force RecyclerView to recharge

3) no onBindViewHolder() I force the Radio selection on the item whose position on the adapter is the same as the sItemSelected variable.

    
29.08.2017 / 23:14