Two checkbox in recyclerview changing state when scrolling

半世苍凉 提交于 2019-12-25 20:05:05

问题


Edit

Solved issue by removing two lines

holder.checkbox.setChecked(mListenerList.get(position).isSelected());
holder.checkbox.setChecked(mListenerList.get(position).isSelected2());

And By Adding

  @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

I am not editing my original code for future developers.

Main Question before Edit Start from Here

I am working on fantasy cricket app where I am selecting the captain and vice captain from a list of 11 player.
I am using a checkbox for selecting the captain and vice captain.

The selection of checkbox is working fine with my code, but the issue is when I select 1st player as a captain(C) and 2nd player as Vice-Captain(VC) and then scroll the list the checkbox state is changing and showing other player selected.

So is there any right way to do that thing?
I have tried many way they are working when there is single checkbox but in my case there is two and only one can be select from the list.

Please refer to the attached screenshots on the bottom for clarity.

Adapter Class

public class AdapterFinalTeamList extends     RecyclerView.Adapter<AdapterFinalTeamList.MyViewHolder> {
    private List<BeanDBTeam> mListenerList;
    Context mContext;
    private  CheckBox lastChecked = null;
    private  int lastCheckedPos = 0;

    private  CheckBox lastChecked2 = null;
    private  int lastCheckedPos2 = 0;

    private RadioButton lastCheckedRB = null;
    private RadioButton lastCheckedRB1 = null;

    TextView PreviousCaptain = null;
    TextView PreviousVC = null;


    public AdapterFinalTeamList(List<BeanDBTeam>              mListenerList, Context context) {
        mContext = context;
        this.mListenerList = mListenerList;

    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv_PlayerName,tv_SelectCaptain,tv_SelectViceCaptain, tv_PlayerTeamName, tv_PlayerPoints,tv_TeamNumber;
        ImageView im_PlayerImage,im_onetwox;
        CheckBox checkbox,checkbox2;

        RadioGroup radiogroup;
        RadioButton radio,radio2;


        public MyViewHolder(View view) {
            super(view);

            tv_PlayerName =view.findViewById(R.id.tv_PlayerName);
            tv_PlayerTeamName = view.findViewById(R.id.tv_PlayerTeamName);
            tv_PlayerPoints = view.findViewById(R.id.tv_PlayerPoints);

            im_PlayerImage = view.findViewById(R.id.im_PlayerImage);
            im_onetwox = view.findViewById(R.id.im_onetwox);


            tv_TeamNumber = view.findViewById(R.id.tv_TeamNumber);
            tv_SelectViceCaptain = view.findViewById(R.id.tv_SelectViceCaptain);
            tv_SelectCaptain= view.findViewById(R.id.tv_SelectCaptain);
            checkbox= view.findViewById(R.id.checkbox);
            checkbox2= view.findViewById(R.id.checkbox2);
            radiogroup= view.findViewById(R.id.radiogroup);
            radio= view.findViewById(R.id.radio);
            radio2= view.findViewById(R.id.radio2);

        }

    }

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

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.adapter_final_list, parent, false);

        return new MyViewHolder(itemView);
    }



    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {



        String id = mListenerList.get(position).getMatchId();

        String arrayList = (mListenerList.get(position).getPlayerData());
        try {
            JSONObject job = new JSONObject(arrayList);

            String PlayerName = job.getString("name");
            String PlayerImage = job.getString("image");
            String PlayerPoints = job.getString("player_points");
            String PlayerCredit = job.getString("credit_points");
            String TeamShortName = job.getString("team_short_name");

            String team_number = job.getString("team_number");
            String player_shortname = job.getString("player_shortname");
            holder.tv_TeamNumber.setText(team_number);
            // PlayerTeam= job.getString("short_name");

            holder.tv_PlayerName.setText(PlayerName);

            holder.tv_PlayerPoints.setText(PlayerPoints);
            holder.tv_PlayerTeamName.setText(TeamShortName);


            Glide.with(activity).load(Config.PLAYERIMAGE + PlayerImage)
                    .crossFade()
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .into(holder.im_PlayerImage);

        } catch (JSONException e) {
            e.printStackTrace();
        }
holder.checkbox.setChecked(mListenerList.get(position).isSelected());
        holder.checkbox.setTag(new Integer(position));

        holder.checkbox.setChecked(mListenerList.get(position).isSelected2());
        holder.checkbox2.setTag(new Integer(position));



        holder.checkbox.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {

                CheckBox cb = (CheckBox) v;
                int clickedPos = ((Integer) cb.getTag()).intValue();
                    holder.checkbox2.setChecked(false);

                    if (cb.isChecked()) {
                        if (lastChecked != null) {
                            mListenerList.get(lastCheckedPos).setSelected(false);
                            lastChecked.setChecked(false);
                        }
                        else if (clickedPos==position){
                            lastCheckedPos = clickedPos;
                            lastChecked = cb;
                            lastChecked.setChecked(true);
                        }
                        lastCheckedPos = clickedPos;
                        lastChecked = cb;
                    } else
                        lastChecked = null;

                    try {
                        lastChecked.setChecked(true);
                    }
                    catch (Exception e){
                        e.printStackTrace();
                    }

                    mListenerList.get(clickedPos).setSelected(cb.isChecked());
                    CaptainId = mListenerList.get(position).getPlayerId();


            }
        });
    holder.checkbox2.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                CheckBox cb = (CheckBox) v;
                int clickedPos = ((Integer) cb.getTag()).intValue();

                holder.checkbox.setChecked(false);

                    if (cb.isChecked()) {
                        if (lastChecked2 != null) {
                            lastChecked2.setChecked(false);
                            mListenerList.get(lastCheckedPos2).setSelected(false);
                        }
                        else if (clickedPos==position){
                            lastChecked2 = cb;
                            lastCheckedPos2 = clickedPos;
                            lastChecked2.setChecked(true);
                        }

                        lastChecked2 = cb;
                        lastCheckedPos2 = clickedPos;
                    } else
                        lastChecked2 = null;

                    try{
                lastChecked2.setChecked(true);
                    }
                    catch (Exception e){
                        e.printStackTrace();
                    }
                    mListenerList.get(clickedPos).setSelected2(cb.isChecked());
                ViceCaptainId = mListenerList.get(position).getPlayerId();

                }

        });


    }

}

adapter_final_list.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res /android"
android:layout_width="match_parent"
android:background="@color/white"
android:layout_height="wrap_content">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="2dp"
    android:padding="5dp"
    android:id="@+id/RL_PlayerListMain"
    android:elevation="0dp">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv_TeamNumber"

    android:visibility="invisible"/>
<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:src="@drawable/logo"
    android:layout_centerVertical="true"
    android:id="@+id/im_PlayerImage"/>
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:id="@+id/RL_Name"
    android:layout_toRightOf="@+id/im_PlayerImage"
    android:layout_marginLeft="10dp">
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Player Name"
    android:id="@+id/tv_PlayerName"
    android:textColor="#1e1e1e"
    />
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center"
    android:layout_below="@+id/tv_PlayerName">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="IND"
        android:layout_gravity="center"
        android:layout_marginRight="5dp"
        android:id="@+id/tv_PlayerTeamName"
        android:textColor="#1e1e1e"
        />
    <View
        android:layout_width="1dp"
        android:layout_height="10dp"
        android:layout_gravity="center"
        android:background="#8e8e8e"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="55 Points"
        android:layout_gravity="center"
        android:id="@+id/tv_PlayerPoints"
        android:textColor="#8e8e8e"
        android:layout_marginLeft="5dp"
        />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:id="@+id/RL_Credit"
    android:layout_alignParentRight="true">
    <TextView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="C"
        android:padding="10dp"
        android:textAlignment="center"
        android:gravity="center"
        android:visibility="gone"
        android:layout_centerVertical="true"
        android:background="@drawable/circle_captain_vc_back"
        android:id="@+id/tv_SelectCaptain"
        android:textColor="#1e1e1e"
        android:layout_marginLeft="10dp"
        />

    <CheckBox
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_toRightOf="@+id/tv_SelectViceCaptain"
        android:layout_centerVertical="true"
        android:visibility="visible"
        android:text="C"
        android:textColor="#1e1e1e"
        android:gravity="center"
        android:button="@android:color/transparent"
        android:background="@drawable/radio_selector"
        android:id="@+id/checkbox"/>
    <CheckBox
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_toRightOf="@+id/checkbox"
        android:layout_centerVertical="true"
        android:visibility="visible"
        android:text="VC"
        android:layout_marginLeft="5dp"
        android:textColor="#1e1e1e"
        android:gravity="center"
        android:button="@android:color/transparent"
        android:background="@drawable/radio_vc_selector"
        android:id="@+id/checkbox2"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/onex_icon"
        android:visibility="invisible"
        android:layout_centerHorizontal="true"
        android:id="@+id/im_onetwox"
        />

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/radiogroup"
        android:visibility="gone"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/im_onetwox"
        android:orientation="horizontal">
    <RadioButton
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_toRightOf="@+id/tv_SelectViceCaptain"
        android:layout_centerVertical="true"
        android:visibility="visible"
        android:text="C"
        android:layout_marginRight="10dp"
        android:gravity="center"
        android:background="@drawable/radio_selector"
        android:button="@android:color/transparent"
        android:id="@+id/radio"/>
    <RadioButton
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_toRightOf="@+id/checkbox"
        android:layout_centerVertical="true"
        android:visibility="visible"
        android:text="VC"
        android:gravity="center"
        android:background="@drawable/radio_vc_selector"
        android:button="@android:color/transparent"
        android:id="@+id/radio2"/>
    </RadioGroup>



    <TextView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="VC"
        android:textAlignment="center"
        android:gravity="center"
        android:visibility="gone"
        android:padding="10dp"
        android:layout_toRightOf="@+id/tv_SelectCaptain"
        android:layout_centerVertical="true"        android:background="@drawable/circle_captain_vc_back"
        android:id="@+id/tv_SelectViceCaptain"
        android:textColor="#1e1e1e"
        android:layout_marginLeft="10dp"
        />


</RelativeLayout>

</RelativeLayout>

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#8e8e8e"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="2dp"
    android:layout_marginRight="5dp"
    android:layout_marginLeft="5dp"
    android:layout_below="@+id/RL_PlayerListMain"/>
 </RelativeLayout>

Selecting C and VC

After scrolling top to bottom and bottom to top

Please ignore Radio group. My code is working fine with checkbox, it's only creating issues when scrolling.


回答1:


For checkbox you need to use checkbox.OnCheckedChangeListener() instead of checkbox.setOnClickListener()

Follow this steps

add a new Boolean variable in your BeanDBTeam class

public class BeanDBTeam
{               
    boolean isChecked;    

    public boolean getisChecked() {
        return isChecked;
    }

    public void setIsChecked(boolean flag) {
        isChecked= flag;
    }
}

Now inside you onBindViewHolder() add below code

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
    BeanDBTeam  bean = mListenerList.get(position).getisChecked()

    // check here the flag and status of checkbox  based on flag
    holder.checkbox2.setChecked(bean.getisChecked());

    holder.checkbox2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
          @Override
          public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
              // set flag of checkbox status  in your list when user check or uncheck the checkbox
             bean.setIsChecked(isChecked);
             notifyDataChanged();
          }
    }); 
 }            



回答2:


This is what recycling behaviour is, You can use other answer that are also correct but as you are having limited entries in your list you can actually disable recycling your recyclerview. Use below code in your adapter:

@Override
public void onBindViewHolder(final CommentViewHolder viewHolder, final int position) {
    viewHolder.setIsRecyclable(false);
}



回答3:


As @Nilesh suggested you , to use the Bean class for checkbox state remember functionality like below:

 /**
 * CheckType ==>>1 For the first checkbox
 * CheckType ==>>2 For the second checkbox
 * CheckType ==>>0 For the None
 */         
public class BeanDBTeam
{
    int checkType;


    public int getCheckType() {
        return checkType;
    }

    public void setCheckType(int checkType) {
        this.checkType = checkType;
    }
}

Inside the MyViewHolder you need to apply the setOnCheckedChangeListener listener and get position from the getAdapterPosition() like below

 public class MyViewHolder extends RecyclerView.ViewHolder {
    TextView tv_PlayerName, tv_SelectCaptain, tv_SelectViceCaptain, tv_PlayerTeamName, tv_PlayerPoints, tv_TeamNumber;
    ImageView im_PlayerImage, im_onetwox;
    CheckBox checkbox, checkbox2;

    RadioGroup radiogroup;
    RadioButton radio, radio2;


    public MyViewHolder(View view) {
        super(view);

        tv_PlayerName = view.findViewById(R.id.tv_PlayerName);
        tv_PlayerTeamName = view.findViewById(R.id.tv_PlayerTeamName);
        tv_PlayerPoints = view.findViewById(R.id.tv_PlayerPoints);

        im_PlayerImage = view.findViewById(R.id.im_PlayerImage);
        im_onetwox = view.findViewById(R.id.im_onetwox);


        tv_TeamNumber = view.findViewById(R.id.tv_TeamNumber);
        tv_SelectViceCaptain = view.findViewById(R.id.tv_SelectViceCaptain);
        tv_SelectCaptain = view.findViewById(R.id.tv_SelectCaptain);
        checkbox = view.findViewById(R.id.checkbox);
        checkbox2 = view.findViewById(R.id.checkbox2);
        radiogroup = view.findViewById(R.id.radiogroup);
        radio = view.findViewById(R.id.radio);
        radio2 = view.findViewById(R.id.radio2);

        /**
         * NOW WE APPLY THE setOnCheckedChangeListener functionality for the checkboxlistener
         */

        checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // set flag of checkbox status  in your list when user check or uncheck the checkbox
                if (checkbox) {
                    YOUR_ARRAYLIST.get(getAdapterPosition()).setCheckType(1);
                }
                else {
                    YOUR_ARRAYLIST.get(getAdapterPosition()).setCheckType(0);
                }
                notifyDataChanged();
            }
        });

        checkbox2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // set flag of checkbox status  in your list when user check or uncheck the checkbox
                if (checkbox) {
                    YOUR_ARRAYLIST.get(getAdapterPosition()).setCheckType(2);
                }
                else {
                    YOUR_ARRAYLIST.get(getAdapterPosition()).setCheckType(0);
                }
                notifyDataChanged();
            }
        });


    }
}

And inside the onBindViewHolder we need to set the Checkbox according to the selection like below

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
    BeanDBTeam  bean = mListenerList.get(position).getisChecked()

    // check here the flag and status of checkbox  based on flag
    if(bean.getCheckType()==0) {
        holder.checkbox.setChecked(false);
        holder.checkbox2.setChecked(false);

    }
    else if(bean.getCheckType()==1) {
        holder.checkbox.setChecked(true);
        holder.checkbox2.setChecked(false);

    }
    else if(bean.getCheckType()==2) {
        holder.checkbox.setChecked(false);
        holder.checkbox2.setChecked(true);

    }

}


来源:https://stackoverflow.com/questions/53957115/two-checkbox-in-recyclerview-changing-state-when-scrolling

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!