问题
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