0

I have a recyclerView containing items presented by 2 Cardviews in the same Layout.
When I click on a Cardview, I want the other cardview to collapse or expand.
It works but when for example I click on card 1, card 9,18,... also expands.
I have read about stableId's and getItemID's but it still doesn't work properly when implemented.
I am now using hashCode to get the itemId as I know that it is implemented in my dataset object and I am sure that it returns a unique ID.
Here is the code :
RecyclerViewAdapter

public class ArrDepRecyclerViewAdapter extends RecyclerView.Adapter<ArrDepRecyclerViewAdapter.ArrDepListItemModelVH> {

    private final boolean arrival;
    private final List<AirportFlightContract> dataSet;
    public ArrDepRecyclerViewAdapter(List<AirportFlightContract> dataSet, boolean arrival) {
        this.dataSet = dataSet;
        this.arrival = arrival;
        setHasStableIds(true);
    }

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

    @Override
    public void onBindViewHolder(@NonNull ArrDepListItemModelVH holder, int position) {

        //topCardView is the card on which I Click
        //subCardView is the card which needs to expand/collapse

        holder.getTopCardView().setOnClickListener(v->{
            if (holder.getSubCardView().getVisibility() == View.GONE) {
                holder.getSubCardView().setVisibility(View.VISIBLE);
            } else {
                holder.getSubCardView().setVisibility(View.GONE);
            }
        });

...

    @Override
    public int getItemCount() {
        if (dataSet != null) {
            return dataSet.size();
        } else {
            return 0;
        }
    }

    @Override
    public long getItemId(int position) {
        return (long) dataSet.get(position).hashCode();
    }
Stefano Sansone
  • 2,377
  • 7
  • 20
  • 39
Mat777
  • 328
  • 1
  • 4
  • 10
  • 3
    I would suggest you save the visibility status in your model `AirportFlightContract`. Because Views gets recycled & state is bound to be lost. – Mayur Gajra Jan 27 '22 at 13:41
  • 1
    `RecyclerView` reuses existing `ViewHolders` which hold a reference to views to set view properties in RecyclerViewAdapter's `onBindViewHolder`. Hence, any properties previously set must be reset for a new RecyclerView item in `onBindViewHolder`. So, the visibility/gone state of a card should be stored as suggested by @MayurGajra in the above comment and checked to set the visibility status of CardViews. (I cannot find the exact reference for the above behavior) – Kalyan Raghu Jan 27 '22 at 17:56
  • Thanks to both of you. It Was indeed the good solution. I've added a property in the model and checked on it. – Mat777 Jan 27 '22 at 18:35

1 Answers1

0

So thanks to the comments on my question, here is a solution to this problem.
I've added an isVisible attribute in my modelObject and used it to set the visibility value of the cardView.
Here is the code:

   @Override
public void onBindViewHolder(@NonNull ArrDepListItemModelVH holder, int position) {
    AirportFlightContract airportFlightContract = dataSet.get(position);
    //Set visibility of the card by checking it's model attribute
    holder.getSubCardView().setVisibility(airportFlightContract.isVisible()?View.VISIBLE:View.GONE);
    holder.getTopCardView().setOnClickListener(v->{
        //Check model to see if the card is visible
        if (!airportFlightContract.isVisible()) {
            //Change visibility and update model
            holder.getSubCardView().setVisibility(View.VISIBLE);
            airportFlightContract.setVisible(true);
        } else {
            holder.getSubCardView().setVisibility(View.GONE);
            airportFlightContract.setVisible(false);
        }
    });
Mat777
  • 328
  • 1
  • 4
  • 10