我有一个cardView自定义布局,里面有一个复选框,我在片段的recyclerView中使用这个cardView(我有3个片段和一个适配器)。
我尝试通过不同的教程为复选框实现setOnCheckedListener,因为我需要知道是否已检查recyclerView内部的所有复选框,并将每个复选框的布尔值放入片段的SparseBooleanArray中。
我的适配器:
public class WarmupProgramAdapter extends RecyclerView.Adapter<WarmupProgramAdapter.ProductViewHolder> {
private Context mCtx;
private List<Program> warmupProgramList;
public WarmupProgramAdapter(Context mCtx, List<Program> warmupProgramList) {
this.mCtx = mCtx;
this.warmupProgramList = warmupProgramList;
}
@NonNull
@Override
public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.custom_program_card_layout, null);
ProductViewHolder holder = new ProductViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull final ProductViewHolder holder, final int position) {
//getting the program of the specified position
final Program program = warmupProgramList.get(position);
//binding the data with the viewholder views
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(program.getImage()));
holder.tvName.setText(program.getName());
holder.tvHow.setText(program.getHow());
holder.tvHint.setText(program.getHint());
holder.checkBox.setChecked(program.getDone());
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (program.getDone()) {
program.setDone(false);
cbWarmupProgramStateArray.put(position, false);
} else {
program.setDone(true);
cbWarmupProgramStateArray.put(position, true);
}
int trueCount = 0;
for (int i = 0; i < cbWarmupProgramStateArray.size(); i++) {
if (cbWarmupProgramStateArray.get(i)) {
trueCount++;
}
if ((trueCount == WarmupFragment.programWarmupList.size())) {
Toast.makeText(mCtx, " ## Program done !", Toast.LENGTH_SHORT).show();
break;
}
}
}
});
}
@Override
public int getItemCount() {
return warmupProgramList.size();
}
static class ProductViewHolder extends RecyclerView.ViewHolder{
TextView tvName, tvHow, tvHint;
ImageView imageView;
CheckBox checkBox;
ProductViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_type_program);
tvName = itemView.findViewById(R.id.tv_name_program);
tvHow = itemView.findViewById(R.id.tv_how_program);
tvHint = itemView.findViewById(R.id.tv_hint_program);
checkBox = itemView.findViewById(R.id.cb_program);
}
}
}
如您所见,我尝试使用setOnClickListener作为复选框,我将所有值都放入了SparseBooleanArray中,但是我不知道是否可以在Fragment中获取此数组,以及这样做是否正确。< / p>
我的片段:
public class WarmupFragment extends Fragment {
RecyclerView recyclerViewWarmup;
RecyclerView.LayoutManager layoutManagerWarmup;
ProgramAdapter programAdapterWarmup;
public static List<Program> programWarmupList;
ArrayList<Program> programWarmupObject;
private OnFragmentInteractionListener mListener;
public WarmupFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View warmupView = inflater.inflate(R.layout.fragment_warmup, container, false);
programWarmupObject = new ArrayList<>();
programWarmupObject.clear();
if (getArguments() != null) {
programWarmupObject = getArguments().getParcelableArrayList("warmupProgramListForFragment");
}
recyclerViewWarmup = warmupView.findViewById(R.id.warmup_recycler_view);
recyclerViewWarmup.setHasFixedSize(false);
layoutManagerWarmup = new LinearLayoutManager(getContext());
recyclerViewWarmup.setLayoutManager(layoutManagerWarmup);
programWarmupList = new ArrayList<>();
programWarmupList.addAll(programWarmupObject);
programAdapterWarmup = new ProgramAdapter(getContext(), programWarmupList);
recyclerViewWarmup.setAdapter(programAdapterWarmup);
return warmupView;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
我的程序对象:
public class Program implements Parcelable {
private int image;
private String name;
private String how;
private String hint;
private boolean isDone;
public Program(Parcel in) {
super();
readFromParcel(in);
}
public static final Parcelable.Creator<Program> CREATOR = new Creator<Program>() {
@Override
public Program createFromParcel(Parcel in) {
return new Program(in);
}
@Override
public Program[] newArray(int size) {
return new Program[size];
}
};
public Program(int image, String name, String how, String hint) {
this.image = image;
this.name = name;
this.how = how;
this.hint = hint;
}
public void readFromParcel(Parcel in) {
image = in.readInt();
name = in.readString();
how = in.readString();
hint = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int i) {
dest.writeInt(image);
dest.writeString(name);
dest.writeString(how);
dest.writeString(hint);
}
@Override
public String toString() {
return image + " , " + name + " , " + how + " , " + hint;
}
public int getImage() {
return image;
}
public String getName() {
return name;
}
public String getHow() {
return how;
}
public String getHint() {
return hint;
}
public boolean getDone() {
return isDone;
}
public void setDone(boolean done) {
isDone = done;
}
@Override
public int describeContents() {
return 0;
}
}
谢谢。
(对不起,我不能点英语)
答案 0 :(得分:1)
好的,您需要做的很简单。
首先,我不知道cbWarmupProgramStateArray
变量来自何处,我看到您正在使用它在Adapter中存储布尔值,但在任何地方都看不到它被声明为字段。根据名称和使用该变量的方式,我的猜测是某种List<Boolean>
。
您不需要具有List<Boolean>
和List<Program>
。 Program
已经有一个布尔字段,您应该使用它来跟踪用户是否检查了程序。
关于与片段的通信。您需要在适配器中声明一个回调接口,例如:
public class WarmupProgramAdapter ... {
interface AdapterCallback {
void isAllChecked();
void programChecked(Program program);
}
...
}
您可以像这样调用回调:
//Do this..
warmupProgramList.get(position).setDone(checkBox.isChecked());
//IDK if your fragment needs to know about individual checks, just added this in case
fragmentCallback.programChecked(warmupProgramList.get(position), checkBox.isChecked());
//Instead of..
//if (checkBox.isChecked()) {
// checkBox.setChecked(true); //There's no need to programatically set the checkbox checked, the checkbox is check before triggering the View.OnClick listener
// cbWarmupProgramStateArray.put(position, true);
//} else {
// checkBox.setChecked(false);
// cbWarmupProgramStateArray.put(position, false);
//}
//And do this..
Boolean allTrue = true;
for (Program program : warmupProgramList) {
if (!program.getDone()) {
allTrue = false;
break;
}
}
if (allTrue) {
fragmentCallback.isAllChecked();
}
//Instead of this...
//int trueCount = 0;
//for (int i = 0; i < cbWarmupProgramStateArray.size(); i++) {
// if (cbWarmupProgramStateArray.get(i)) {
// trueCount++;
// }
// if ((trueCount == WarmupFragment.programWarmupList.size())) {
// Toast.makeText(mCtx, " ## Program done !", Toast.LENGTH_SHORT).show();
// break;
// }
//}
fragmentCallback
字段是接口AdapterCallback。它应该由片段实现,并且应该将其传递给适配器的构造函数。