Single selection in RecyclerView

后端 未结 15 980
深忆病人
深忆病人 2020-11-22 15:15

I know there are no default selection methods in recyclerview class, But I have tried in following way,

public void onBindViewHolder(ViewHolder holder, final         


        
相关标签:
15条回答
  • 2020-11-22 16:11

    This is how its looks

    Inside your Adapter

    private int selectedPosition = -1;
    

    And onBindViewHolder

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    
        if (selectedPosition == position) {
            holder.itemView.setSelected(true); //using selector drawable
            holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.white));
        } else {
            holder.itemView.setSelected(false);
            holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.black));
        }
    
        holder.itemView.setOnClickListener(v -> {
            if (selectedPosition >= 0)
                notifyItemChanged(selectedPosition);
            selectedPosition = holder.getAdapterPosition();
            notifyItemChanged(selectedPosition);
        });
    }
    

    Thats it! As you can see i am just Notifying(updating) previous selected item and newly selected item

    My Drawable set it as a background for recyclerview child views

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="false" android:state_selected="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/blue" />
        </shape>
    </item>
    

    0 讨论(0)
  • 2020-11-22 16:13

    This is how the Adapter class looks like :

    public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder>{
    
    Context context;
    ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList_;
    public int  lastSelectedPosition=-1;
    
    
    public MyRecyclerViewAdapter(Context context, ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList)
    {
        this.context = context;
        this.routeDetailsFromFirestoreArrayList_ = routeDetailsFromFirestoreArrayList;
    }
    
    @NonNull
    @Override
    public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
    {
        // LayoutInflater layoutInflater = LayoutInflater.from(mainActivity_.getBaseContext());
        LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
        View view = layoutInflater.inflate(R.layout.route_details, viewGroup, false);
        return new MyRecyclerViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(@NonNull final MyRecyclerViewHolder myRecyclerViewHolder, final int i) {
    
        /* This is the part where the appropriate checking and unchecking of radio button happens appropriately */
        myRecyclerViewHolder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if(b) {
                    if (lastSelectedPosition != -1) {
         /* Getting the reference to the previously checked radio button and then unchecking it.lastSelectedPosition has the index of the previously selected radioButton */  
                        //RadioButton rb = (RadioButton) ((MainActivity) context).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
                        RadioButton rb = (RadioButton) ((MainActivity) myRecyclerViewHolder.mRadioButton.getContext()).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
                        rb.setChecked(false);
                    }
                        lastSelectedPosition = i;
                        /* Checking the currently selected radio button */
                        myRecyclerViewHolder.mRadioButton.setChecked(true);
                    }
            }
        });
    }
    
    @Override
    public int getItemCount() {
        return routeDetailsFromFirestoreArrayList_.size();
    }
    } // End of Adapter Class
    

    Inside MainActivity.java we call the ctor of Adapter class like this. The context passed is of MainActivity to the Adapter ctor :

    myRecyclerViewAdapter = new MyRecyclerViewAdapter(MainActivity.this, routeDetailsList);
    
    0 讨论(0)
  • 2020-11-22 16:14

    You need to clear the OnCheckedChangeListener before setting setChecked():

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
    
        holder.mRadioButton.setOnCheckedChangeListener(null);
        holder.mRadioButton.setChecked(position == mCheckedPosition);
        holder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    
                mCheckedPosition = position;
                notifyDataSetChanged();
            }
        });
    }
    

    This way it won't trigger the java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling error.

    0 讨论(0)
提交回复
热议问题