在 Recycler 视图中滚动时复选框状态不断变化

CheckBox States Keep Changing While Scrolling in Recycler View

我正在尝试为我的大学制作一个考勤应用程序。我在 Recycler View 中使用 CardView。在我的 Card View 中有一个复选框,用于标记特定学生的出勤情况。问题是,如果我标记说,学生 1,2 和 3。位置 10,11,12 或其他任何东西(随机)上的一些随机卡片会自行标记。我知道这是因为回收站视图回收了这些卡片的位置,但不幸的是,由于我是开发新手,我不知道如何实现复选框来给我检查卡片的详细信息,以便我可以使用它。我已经阅读了一些指南,但一直无法理解。我在下面附加了我的适配器 Class 和 takeAttendance Activity。我还没有实现任何与复选框相关的东西,需要同样的指导。

回收器视图适配器 CLASS

package com.pkg.attendanceapp;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.textview.MaterialTextView;

import java.util.ArrayList;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.StudentListViewHolder> {
    private ArrayList<StudentList> studentList;
    private ArrayList<String> presentStudents;
    private ArrayList<StudentList> absentStudents;

    public static class StudentListViewHolder extends RecyclerView.ViewHolder {

        private MaterialTextView studentName;
        private MaterialTextView studentRoll;
        private MaterialTextView attendanceTextview;
        private MaterialCheckBox checkBox;


        public StudentListViewHolder(@NonNull final View itemView) {
            super(itemView);

            studentName = itemView.findViewById(R.id.stdName);
            studentRoll = itemView.findViewById(R.id.stdRoll);
            checkBox = itemView.findViewById(R.id.checkBox);
            attendanceTextview = itemView.findViewById(R.id.studentAttendance);

        }
    }

    public RecyclerViewAdapter(ArrayList<StudentList> mStudentList){

        studentList = mStudentList;
        absentStudents = mStudentList;
    }

    @Override
    public StudentListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new StudentListViewHolder(LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_view, parent, false));

    }
    @Override
    public void onBindViewHolder(@NonNull final StudentListViewHolder holder, int position) {
        StudentList currentStudent = studentList.get(position);

        holder.studentName.setText(currentStudent.getStudName());
        holder.studentRoll.setText(currentStudent.getStudRoll());

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

    }
}

ACTIVITY

package com.pkg.attendanceapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.DialogInterface;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.google.android.gms.tasks.Task;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textview.MaterialTextView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

public class takeAttendance extends AppCompatActivity {

    DatabaseReference AttendanceDatabaseReference;
    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    public ArrayList<StudentList> studentListArray;
    //private String date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_attendance);

        //FloatingActionButton saveBtn = findViewById(R.id.floatingActionButton);
        recyclerView = findViewById(R.id.mRecyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);
        recyclerViewAdapter = new RecyclerViewAdapter(studentListArray);
        recyclerView.setAdapter(recyclerViewAdapter);
        studentListArray = new ArrayList<>();



        AttendanceDatabaseReference = FirebaseDatabase.getInstance().getReference("studentsInfo");
        AttendanceDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull final DataSnapshot dataSnapshot) {

                findViewById(R.id.progressBar).setVisibility(View.GONE);

                for (DataSnapshot mDataSnapshot : dataSnapshot.getChildren()){
                    StudentList studentsList = mDataSnapshot.getValue(StudentList.class);
                    studentListArray.add(studentsList);
                }

                recyclerViewAdapter = new RecyclerViewAdapter(studentListArray);
                recyclerView.setAdapter(recyclerViewAdapter);

            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

                // Toast.makeText(takeAttendance.this, "Oops! Something Went Wrong...", Toast.LENGTH_LONG).show();
            }
        });
    }
 }

我之前遇到过这个问题,解决方案是您必须保存模型中每个复选框的布尔值 class,如果选中则为 true,否则为 false。

基于其他 Posts/Guides,它是这样工作的 -

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

private ArrayList<StudentList> studentList;
private ArrayList<String> mRollNum;
private Activity activity;
private OnCheckBoxClickListener mListener;

private SparseBooleanArray itemStateArray = new SparseBooleanArray();

public interface OnCheckBoxClickListener {

    void onCheckBoxClick(int position, boolean isChecked);
}

void setOnCheckBoxClickListener(OnCheckBoxClickListener listener){

    mListener = listener;
}

 class ViewHolder extends RecyclerView.ViewHolder {

    private MaterialTextView studentName;
    private MaterialTextView studentRoll;
    private MaterialTextView attendanceStatus;
    MaterialCheckBox mCheckbox;

    ViewHolder(@NonNull View itemView, final OnCheckBoxClickListener listener) {
        super(itemView);

        studentName = itemView.findViewById(R.id.stdName);
        studentRoll = itemView.findViewById(R.id.stdRoll);
        attendanceStatus = itemView.findViewById(R.id.studentAttendance);
        mCheckbox = itemView.findViewById(R.id.checkBox);

        mCheckbox.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("SetTextI18n")
            @Override
            public void onClick(View view) {

                int adapterPosition = getAdapterPosition();
                if (!itemStateArray.get(adapterPosition, false)) {
                    attendanceStatus.setTextColor(Color.GREEN);
                    attendanceStatus.setText("Present");
                    mCheckbox.setChecked(true);
                    itemStateArray.put(adapterPosition, true);
                    listener.onCheckBoxClick(adapterPosition, true);

                }
                else  {
                    mCheckbox.setChecked(false);
                    itemStateArray.put(adapterPosition, false);
                    listener.onCheckBoxClick(adapterPosition, false);
                    attendanceStatus.setTextColor(Color.RED);
                    attendanceStatus.setText("Absent");


                }


            }
        });
    }

    @SuppressLint("SetTextI18n")
    void bind(int position) {

        if (!itemStateArray.get(position, false)) {
            mCheckbox.setChecked(false);
            attendanceStatus.setTextColor(Color.RED);
            attendanceStatus.setText("Absent");

        }
        else {
            attendanceStatus.setTextColor(Color.GREEN);
            attendanceStatus.setText("Present");
            mCheckbox.setChecked(true);

        }
    }
}

RecyclerViewAdapter(Activity activity, ArrayList<StudentList> mStudentList, ArrayList<String> rollNum ) {
    studentList = mStudentList;
    this.activity = activity;
    this.mRollNum = rollNum;

}

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

    View studentListView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_view, parent, false);

    return new ViewHolder(studentListView, mListener);
}

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

    StudentList currentStudent = studentList.get(position);

    holder.studentName.setText(currentStudent.getStudName());
    holder.studentRoll.setText(currentStudent.getStudRoll());

    holder.bind(position);
}

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