如何在Recyclerview中仅选择一个复选框并更改notifydataset

时间:2016-08-24 15:06:48

标签: android checkbox android-recyclerview

在我的代码中,我创建了带有复选框的recyclerview,并且已经选择了默认的一个项目。现在我想要选择其他项目复选框,所以取消选择所有其他项目意味着一个项目在时间选择。

我的适配器代码:

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

ArrayList<SupportSchoolIdModel> supportSchoolIdModels;
DataPref mDataPref;
String supportSchoolId;

public SupportSchoolIdAdapter(List<SupportSchoolIdModel> supportSchoolIdModels) {
    this.supportSchoolIdModels = new ArrayList<>(supportSchoolIdModels);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    mDataPref = DataPref.getInstance(context);
    supportSchoolId = mDataPref.getSupportSchoolId();
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.support_school_item, parent, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    final SupportSchoolIdModel event = supportSchoolIdModels.get(position);
    holder.bindData(supportSchoolIdModels.get(position));

    //in some cases, it will prevent unwanted situations
    holder.checkbox.setOnCheckedChangeListener(null);

    //if true, your checkbox will be selected, else unselected
    holder.checkbox.setChecked(supportSchoolIdModels.get(position).isSelected());

    holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            supportSchoolIdModels.get(holder.getAdapterPosition()).setSelected(isChecked);
        }
    });
    if (supportSchoolIdModels.get(position).getPkSchoolId().equalsIgnoreCase(supportSchoolId)) {
        holder.checkbox.setChecked(true);
    } else {
        holder.checkbox.setChecked(false);
    }
}
@Override
public int getItemCount() {
    return supportSchoolIdModels.size();
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    private TextView schoolIdTxt;
    private TextView schoolNameTxt;
    private CheckBox checkbox;

    public ViewHolder(View v) {
        super(v);
        schoolIdTxt = (TextView) v.findViewById(R.id.schoolIdTxt);
        schoolNameTxt = (TextView) v.findViewById(R.id.schoolNameTxt);
        checkbox = (CheckBox) v.findViewById(R.id.checkbox);
    }
    public void bindData(SupportSchoolIdModel supportSchoolIdModel) {
        schoolIdTxt.setText(supportSchoolIdModel.getPkSchoolId());
        schoolNameTxt.setText(supportSchoolIdModel.getSchoolName());
    }
}
}

第二个问题是当我滚动回收视图时为什么选中的项目未选中。请帮帮我。

6 个答案:

答案 0 :(得分:13)

1-您可以在Adapter类中创建一个可用于保存所选位置的变量:

private int selectedPosition = -1;// no selection by default

2-内部 onBindViewHolder 设置检查状态:

holder.checkBox.setChecked(selectedPosition == position);

3-在 setOnCheckedChangeListener 内,您必须更新位置

this.selectedPosition = holder.getAdapterPosition();

4-刷新适配器

adapter.notifyDatasetChanged();

<强> 修改

将为所有职位调用

onBindViewHolder

因此,所有CheckBox都会调用 setChecked 方法, 这个方法有一个布尔输入。

在上面的示例中,我写了setChecked(selectedPosition == position)。为了更具可读性,我可以写:

if(selectedPosition == position){ 
   holder.checkBox.setChecked(true);
}
else{
   holder.checkBox.setChecked(false) 
}

答案 1 :(得分:3)

这是最好的代码! 关于BindViewHolder的通知

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

private Context context;
ArrayList<SupportSchoolIdModel> supportSchoolIdModels;
private int selectedPosition = 0;
private ArrayList<Integer> selectCheck = new ArrayList<>();

public SupportSchoolIdAdapter (Context context, ArrayList<SupportSchoolIdModel> supportSchoolIdModels) {
    this.context = context;
    this.supportSchoolIdModels = supportSchoolIdModels;

//initilize selectCheck 
    for (int i = 0; i < supportSchoolIdModels.size(); i++) {
        selectCheck.add(0);
    }

}

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

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

    if (selectCheck.get(position) == 1) {
        holder.checkbox.setChecked(true);
    } else {
        holder.checkbox.setChecked(false);
    }

    holder.checkbox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            for(int k=0; k<selectCheck.size(); k++) {
                if(k==position) {
                    selectCheck.set(k,1);
                } else {
                    selectCheck.set(k,0);
                }
            }
            notifyDataSetChanged();

        }
    });
    holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            if(isChecked==true){
                //Do whatever you want to do with selected value
            }
        }
    });

}

@Override
public int getItemCount() {
    return supportSchoolIdModels== null? 0: supportSchoolIdModels.size();
}

class ViewHolder extends RecyclerView.ViewHolde {

    CheckBox checkbox;

    public ViewHolder(View v) {
        super(v);
        checkbox = (CheckBox) v.findViewById(R.id.checkbox);          
    }

}

}

答案 2 :(得分:0)

正如你所说,你是Android的新手首先你会注意到你的复选框将有回收者视图的问题。你在回收视图中选择了一些项目,滚动后你会发现一些其他项目被选中来解决这个问题你需要关注this answer。 要么 您需要在School Model类中创建一个布尔变量(以捕获Recycler视图中每个项目的复选框的状态),如下所示

 class SchoolModel{
    private boolean isChecked;
    public boolean isChecked(){
     return ischecked;}

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

第二个问题是只选择一个复选框并取消选择其余的复选框,你需要编写逻辑(Check here for solution)。一个主要的代码更改是将setOnCheckedChangeListener移动到查看holder类,因为每次都调用bindviewholder你更新你的recyclerview,因此每次都设置setOnCheckedChangeListener是不正确的。所以你把这个监听器放在视图持有者中,这将只为每个复选框监听器分配一次。

 checkBoxDeleteComment.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               //your code
            }
        });

答案 3 :(得分:0)

公共类MyTeamAdapter扩展了RecyclerView.Adapter {     私有上下文;     private ArrayList myTeams;

private int prevSelection = -1;


public MyTeamAdapter(Context context, ArrayList<Team> myTeams) {
    this.context = context;
    this.myTeams = myTeams;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_my_team, parent, false));
}


@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
    final Team team = myTeams.get(position);
    ViewHolder viewHolder = (ViewHolder) holder;

    if (team.isTeamSelected()) {
        viewHolder.checkTeam.setChecked(true);
        prevSelection = position;
    } else {
        viewHolder.checkTeam.setChecked(false);
    }

    viewHolder.checkTeam.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (b) {
                team.setTeamSelected(true);
                if (prevSelection >= 0) {
                    myTeams.get(prevSelection).setTeamSelected(false);
                    notifyItemChanged(prevSelection);
                }
                prevSelection = position;
            } else {
                team.setTeamSelected(false);
            }
        }
    });
}

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

public class ViewHolder extends RecyclerView.ViewHolder {
    RelativeLayout captainHolder, viceCaptainHolder;
    CheckBox checkTeam;
    TextView tvTeamName, tvCaptainName, tvCaptain, tvVCapName, tvVC, tvWcktKeeper, tvBatsMen, tvAllRounder, tvBowler;
    ImageView edtTeam, viewTeam, copyTeam;


    public ViewHolder(View itemView) {
        super(itemView);
        checkTeam = itemView.findViewById(R.id.cb_team);

        tvTeamName = itemView.findViewById(R.id.tv_team_name);

        captainHolder = itemView.findViewById(R.id.captain_holder);
        tvCaptainName = captainHolder.findViewById(R.id.tv_player_name);
        tvCaptain = captainHolder.findViewById(R.id.tv_player_type);

        viceCaptainHolder = itemView.findViewById(R.id.vc_holder);
        tvVCapName = viceCaptainHolder.findViewById(R.id.tv_player_name);
        tvVC = viceCaptainHolder.findViewById(R.id.tv_player_type);

        tvWcktKeeper = itemView.findViewById(R.id.tv_wckt_keeper);
        tvBatsMen = itemView.findViewById(R.id.tv_bats_men);
        tvAllRounder = itemView.findViewById(R.id.tv_all_rounder);
        tvBowler = itemView.findViewById(R.id.tv_baller);

        edtTeam = itemView.findViewById(R.id.edt_team);
        viewTeam = itemView.findViewById(R.id.view_team);
        copyTeam = itemView.findViewById(R.id.copy_team);

    }
}

}

答案 4 :(得分:0)

您可以使用以下代码;肯定会对你们有帮助,

int selectedPosition=0;

 if (selectedPosition == position) {
            holder.itemView.setSelected(true); //using selector drawable


            GradientDrawable drawable = (GradientDrawable) holder.ll_portal.getBackground();
            drawable.setColor(getResources().getColor(R.color.darkorange));
            holder.tvPortalName.setTextColor(Color.parseColor("#FFFFFF"));


        } else {
            holder.itemView.setSelected(false);
            GradientDrawable drawable = (GradientDrawable) holder.ll_portal.getBackground();
            drawable.setColor(getResources().getColor(R.color.white));
            holder.tvPortalName.setTextColor(Color.parseColor("#000000"));
        }

        final int finalPosition = position;
        holder.ll_portal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                totalDineInOrder= String.valueOf(gallaryModels.get(position).getDineInTotalOrder());
                totalPickupOrder= String.valueOf(gallaryModels.get(position).getPickupTotalOrder());
                selectedPosition= finalPosition;
                notifyDataSetChanged();
            }
        });

答案 5 :(得分:0)

尝试这个完整的示例
公共类ChildAddressAdapter扩展了RecyclerView.Adapter {

private Activity context;
private List<AddressDetail> addressDetailList;
private int selectedPosition = -1;

public ChildAddressAdapter(Activity context, List<AddressDetail> addressDetailList) {
    this.context = context;
    this.addressDetailList = addressDetailList;
}

@NonNull
@Override
public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    LayoutInflater inflater = LayoutInflater.from(context);
    View myView = inflater.inflate(R.layout.address_layout, parent, false);
    return new CartViewHolder(myView);
}

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

    holder.adress_checkbox.setOnClickListener(view -> {
        selectedPosition = holder.getAdapterPosition();
        notifyDataSetChanged();
    });

    if (selectedPosition==position){
        holder.adress_checkbox.setChecked(true);
    }
    else {
        holder.adress_checkbox.setChecked(false);
    }


}

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

class CartViewHolder extends RecyclerView.ViewHolder
{
    TextView address_text,address_tag;
    CheckBox adress_checkbox;

    CartViewHolder(View itemView) {
        super(itemView);
        address_text = itemView.findViewById(R.id.address_text);
        address_tag = itemView.findViewById(R.id.address_tag);
        adress_checkbox = itemView.findViewById(R.id.adress_checkbox);
    }
}

}