Bot
Bot

Reputation: 632

How to highlight the first row of RecyclerView by default and then remove highlight as and when other rows are selected?

I am trying to load a list in RecyclerView and show the first row of the list as selected. I have achieved it using the following code:

@Override
public void onBindViewHolder(NavigationDrawerAdapter.ViewHolder holder, final int position) {

    if (!mNavClassrooms.get(position).equals("")) {
            holder.mTextViewClassroom.setText(mNavClassrooms.get(position)); // Setting the Text with the array of our Titles
            holder.mRelLayClassroom.setSelected(mSelectedItems.get(position, false));

            /*
            The following code was written to make the first item in the Classroom list as selected.
            It leads to the item always being selected and hence has been commented out.
             */
            if(position == 0 && intOldSelectedItem == -1){
                holder.mRelLayClassroom.setSelected(mSelectedItems.get(position, true));
                intOldSelectedItem = 0;
                mSelectedView = holder.mRelLayClassroom.getChildAt(position);
                mSelectedItems.put(position, true);
            }
            else{
                holder.mRelLayClassroom.setSelected(mSelectedItems.get(position, false));
            }
        } else {
            holder.mTextViewClassroom.setText("No classes found");
            holder.mTextViewClassroom.setPadding(40, 0, 0, 0);
        }

        holder.mRelLayClassroom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mSharedPreferences = mContext.getSharedPreferences(Constants.AAPREFERENCES, Context.MODE_PRIVATE);

                String strClassroomValue = mNavClassrooms.get(position);
                int strClassroomName = mNavClassroomNames.get(position);
                SharedPreferences.Editor editor = mSharedPreferences.edit();
                editor.putString(Constants.CLASSROOM_VALUE, strClassroomValue);
                editor.putInt(Constants.CLASSROOM_NAME, strClassroomName);
                editor.commit();

                /*
                We are storing the position of the selected row in the SparseBooleanArray.
                We delete it in case another row has been selected.
                 */
                if (mSelectedItems.get(position, false)) {
                    /*
                    Do nothing
                     */
                } else {
                    mSelectedItems.put(position, true);

                    /*
                    Making sure that the delete code is called only if some view is selected
                     */
                    if (mSelectedView != null) {
                        mSelectedView.setSelected(false);
                        mSelectedItems.delete(intOldSelectedItem);
                        view.setSelected(false);
                    }

                    mSelectedView = view;
                    intOldSelectedItem = position;
                    view.setSelected(true);
                }

}

However, now the first row stays selected always. I am unable to deselect it. I cannot seem to get this working.

I referred to the following answer to achieve most of this functionlaity.

https://stackoverflow.com/a/29984220/2186220

Any help will be appreciated.

Upvotes: 4

Views: 5024

Answers (3)

Onregs
Onregs

Reputation: 430

  1. Add background selector to your ViewHolder layout.
  2. Create your selector handler something like this:

    public class SingleSelector { private View oldVIew; public void setSelection(View newView) { if (oldVIew == null) { newView.setSelected(true); oldVIew = newView; } else { oldVIew.setSelected(false); newView.setSelected(true); oldVIew = newView; } } }

  3. Set default selection when you need it:

    @Override public void onBindViewHolder(SimpleViewHolder holder, int position) { if (position == 0) { singleSelector.setSelection(holder.itemView); } }

  4. In your ViewHolder add listener to itemView and pass it to the handler:

    itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { singleSelector.setSelection(itemView); } });

Upvotes: 0

reVerse
reVerse

Reputation: 35264

I'm not answering your question by posting a fixed version of your onBindViewHolder method since it's kinda hard to understand and we don't know how the rest of your adapter looks like. So following a RecyclerView Adapter which does what you want: Selecting the first row by default and deselecting it once a other row is selected.

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

    // ... other fields
    // default selection position is the first one
    private int selectedPosition = 0;

    // ... constructor etc.

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        if(position == selectedPosition){
            holder.itemView.setSelected(true);
        } else {
            holder.itemView.setSelected(false);
        }

        // Actual selection / deselection logic
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int currentPosition = holder.getLayoutPosition();
                if(selectedPosition != currentPosition){
                    // Temporarily save the last selected position
                    int lastSelectedPosition = selectedPosition;
                    // Save the new selected position
                    selectedPosition = currentPosition;
                    // update the previous selected row
                    notifyItemChanged(lastSelectedPosition);
                    // select the clicked row
                    holder.itemView.setSelected(true);
                }
            }
        });
        // other adapter code
    }

    // other adapter stuff like onCreateViewHolder, getItemCount, ViewHolder etc.
}

Note: I guess there's no need to use a SparseBooleanArray so simply remove it and replace it with the int field used in the example above.

Upvotes: 7

Dhruvi
Dhruvi

Reputation: 1981

Initialize your

int intOldSelectedItem=0 and keep one boolean isVisible= false;

And do it as below:

if (holder.getPosition() == intOldSelectedItem) {
        if (isVisible) {
            //background for selected item
        } else {
        //background for unselected item
        }
} else {
        //background for unselected item
}

holder.mRelLayClassroom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
            if (intOldSelectedItem== holder.getPosition()) {
                isVisible = !isVisible;
            } else {
                if (intOldSelectedItem!= 0) {
                    isVisible = false;
                    notifyItemChanged(intOldSelectedItem);
                }
                isVisible = true;
            }
            intOldSelectedItem= holder.getPosition();
            notifyItemChanged(intOldSelectedItem);
        }
    });

I hope it might help you.

Upvotes: 0

Related Questions