使用RecyclerView时重复显示同一行数据的问题求助
问题:RecyclerView重复显示数据库第一行数据
我创建了名为studentList的ArrayList用于存储从数据库获取的所有数据,但填充RecyclerView时,仅数据库的第一行数据被重复显示。
数据库数据
1 deveah 79 98 99 96 293 97 A+ 2 tejas 78 73 75 78 226 75 A 3 sidhesh 96 56 59 58 173 57 B 4 rishabh 58 78 49 38 165 55 B 5 devesh 45 79 96 82 257 85 A 6 Akshay 5 99 76 94 269 89 A
异常显示截图

DatabaseHelper类
package com.devesh.sqlitedatabase.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import androidx.annotation.Nullable; import com.devesh.sqlitedatabase.db.model.Student; import java.util.ArrayList; public class StudentDatabasaeHelper extends SQLiteOpenHelper { private static final String STUDENT_DATABASE = "student.db"; private static final String STUDENT_TABLE = "studentsInfo"; public StudentDatabasaeHelper( Context context) { super(context,STUDENT_DATABASE,null,1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " + STUDENT_TABLE + " (ID Integer Primary Key AutoIncrement,STUDENT_NAME text,STUDENT_ROLLNO text,CHEMISTRY Integer,PHYSICS Integer,MATH Integer,TOTAL_MARKS Integer,PERCENTAGE Integer,GRADE text)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists " + STUDENT_TABLE); onCreate(db); } public boolean InsertStudentData(String roll_no,String name,int chemistry,int physics, int math,int total_marks,int percentage, String grade){ SQLiteDatabase db = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put("STUDENT_NAME",name); contentValues.put("STUDENT_ROLLNO",roll_no); contentValues.put("CHEMISTRY",chemistry); contentValues.put("PHYSICS",physics); contentValues.put("MATH",math); contentValues.put("TOTAL_MARKS",total_marks); contentValues.put("PERCENTAGE",percentage); contentValues.put("GRADE",grade); long result = db.insert(STUDENT_TABLE,null,contentValues); if(result == -1) return false; else return true; } public ArrayList<Student> GetStudentData(){ SQLiteDatabase db = this.getReadableDatabase(); String query = "select * from " + STUDENT_TABLE; Cursor cursor = db.rawQuery(query,null); Student model = new Student(); ArrayList<Student> allStudents = new ArrayList<Student>(); while (cursor.moveToNext()){ model.NAME = cursor.getString(1); model.ROLL_NO = cursor.getString(2); model.CHEMISTRY = cursor.getInt(3); model.PHYSICS = cursor.getInt(4); model.MATH = cursor.getInt(5); model.TOTAL_MARKS = cursor.getInt(6); model.PERCENTAGE = cursor.getInt(7); model.GRADE = cursor.getString(8); allStudents.add(model); } return allStudents; } }
Student Model类
package com.devesh.sqlitedatabase.db.model; public class Student { public int ID; public String NAME; public String ROLL_NO; public int CHEMISTRY; public int MATH; public int PHYSICS; public int TOTAL_MARKS; public int PERCENTAGE; public String GRADE; // public Student(int id, String name, String roll_no, int total_marks, int percentage, String grde){ // this.ID = id; // this.NAME = name; // this.ROLL_NO = roll_no; // this.TOTAL_MARKS = total_marks; // this.PERCENTAGE = percentage; // this.GRADE = grde; // } // }
ViewActivity类
package com.devesh.sqlitedatabase; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.util.Log; import android.widget.LinearLayout; import com.devesh.sqlitedatabase.db.StudentDatabasaeHelper; import com.devesh.sqlitedatabase.db.model.Student; import java.util.ArrayList; import java.util.List; public class ViewActivity extends AppCompatActivity { RecyclerView recyclerView; LinearLayoutManager linearLayoutManager; ArrayList<Student> studentList; // ArrayList<Student> viewList = new ArrayList<>(); RecyclerAdapter recyclerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view); initData(); initRecyclerView(); } private void initData() { StudentDatabasaeHelper db = new StudentDatabasaeHelper(this); studentList = db.GetStudentData(); // String name = "",roll_no= "",total_marks= "",percent= "",grade= ""; // int id=0,total=0,percentage=0; // Student obj = new Student(); // int i=0; // while (i != studentList.size()) { // obj.ID = studentList.get(i).ID; // obj.NAME = studentList.get(i).NAME; // obj.ROLL_NO =studentList.get(i).ROLL_NO; // obj.TOTAL_MARKS = studentList.get(i).TOTAL_MARKS; // // String total_marks = String.valueOf(total); // obj.PERCENTAGE = studentList.get(i).PERCENTAGE; // //String percent = String.valueOf(percentage); // obj.GRADE = studentList.get(i).GRADE; // viewList.add(obj); // i++; // } Log.d("rogd", "initData: " + studentList.get(1).NAME ); } private void initRecyclerView() { recyclerView = findViewById(R.id.Student_list_recyclerView); linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(RecyclerView.VERTICAL); recyclerView.setLayoutManager(linearLayoutManager); recyclerAdapter = new RecyclerAdapter(studentList); recyclerView.setAdapter(recyclerAdapter); if(recyclerAdapter !=null){ recyclerAdapter.notifyDataSetChanged(); } } }
RecyclerAdapter类
package com.devesh.sqlitedatabase; import android.content.Context; import android.database.Cursor; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.devesh.sqlitedatabase.db.model.Student; import java.util.ArrayList; import java.util.List; public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { ArrayList<Student> studentList; public RecyclerAdapter(ArrayList<Student> studentList){ this.studentList = studentList; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { Student st = studentList.get(position); int id = st.ID; String strID = String.valueOf(id); String name = st.NAME; String roll_no = st.ROLL_NO; // int chemistry = studentList.get(position).CHEMISTRY; // int math = studentList.get(position).MATH; // int physics = studentList.get(position).PHYSICS; int total_marks = st.TOTAL_MARKS; String strTotal_Marks = String.valueOf(total_marks); int percentage = st.PERCENTAGE; String strPercentage = percentage + "%"; String grade = st.GRADE; ViewHolder.setData(strID,name,roll_no,strTotal_Marks,strPercentage,grade); Log.d("rogd", "onBindViewHolder: " + position); } @Override public int getItemCount() { return studentList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder{ private static TextView srno; private static TextView roll_no; private static TextView name; private static TextView total_marks; private static TextView percentage; private static TextView grade; public ViewHolder(@NonNull View itemView) { super(itemView); srno = itemView.findViewById(R.id.srNo_tv); roll_no = itemView.findViewById(R.id.rollno_tv); percentage = itemView.findViewById(R.id.percentage_tv); name = itemView.findViewById(R.id.name_tv); total_marks = itemView.findViewById(R.id.totalMarks_tv); grade = itemView.findViewById(R.id.grade_tv); } public static void setData(String ID, String name1, String roll_no1, String total_marks1, String percentage1, String grade1){ srno.setText(ID); name.setText(name1); roll_no.setText(roll_no1); total_marks.setText(total_marks1); percentage.setText(percentage1); grade.setText(grade1); } } }
问题根源与修复方案
核心问题
- 数据库查询复用同一对象:
GetStudentData方法中,Student实例创建在循环外部,每次循环仅更新该对象属性并添加到集合,导致集合内所有元素指向同一对象,最终显示的是最后一次赋值的数据(或因引用问题显示重复条目)。 - ViewHolder控件声明为static:
ViewHolder内的TextView被标记为static,所有条目共用同一组控件引用,后续绑定会覆盖之前的内容。
修复步骤
1. 修复数据库查询方法
将Student实例创建移至循环内部,确保每条数据对应独立对象,同时补充ID字段赋值:
public ArrayList<Student> GetStudentData(){ SQLiteDatabase db = this.getReadableDatabase(); String query = "select * from " + STUDENT_TABLE; Cursor cursor = db.rawQuery(query,null); ArrayList<Student> allStudents = new ArrayList<Student>(); while (cursor.moveToNext()){ Student model = new Student(); model.ID = cursor.getInt(0); model.NAME = cursor.getString(1); model.ROLL_NO = cursor.getString(2); model.CHEMISTRY = cursor.getInt(3); model.PHYSICS = cursor.getInt(4); model.MATH = cursor.getInt(5); model.TOTAL_MARKS = cursor.getInt(6); model.PERCENTAGE = cursor.getInt(7); model.GRADE = cursor.getString(8); allStudents.add(model); } cursor.close(); return allStudents; }
2. 移除ViewHolder控件的static修饰符
修改ViewHolder类,将控件改为实例属性,同时调整setData方法为非static:
public static class ViewHolder extends RecyclerView.ViewHolder{ private TextView srno; private TextView roll_no; private TextView name; private TextView total_marks; private TextView percentage; private TextView grade; public ViewHolder(@NonNull View itemView) { super(itemView); srno = itemView.findViewById(R.id.srNo_tv); roll_no = itemView.findViewById(R.id.rollno_tv); percentage = itemView.findViewById(R.id.percentage_tv); name = itemView.findViewById(R.id.name_tv); total_marks = itemView.findViewById(R.id.totalMarks_tv); grade = itemView.findViewById(R.id.grade_tv); } public void setData(String ID, String name1, String roll_no1, String total_marks1, String percentage1, String grade1){ srno.setText(ID); name.setText(name1); roll_no.setText(roll_no1); total_marks.setText(total_marks1); percentage.setText(percentage1); grade.setText(grade1); } }
3. 调整Adapter的绑定逻辑
修改onBindViewHolder,调用当前ViewHolder实例的setData方法:
@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { Student st = studentList.get(position); int id = st.ID; String strID = String.valueOf(id); String name = st.NAME; String roll_no = st.ROLL_NO; int total_marks = st.TOTAL_MARKS; String strTotal_Marks = String.valueOf(total_marks); int percentage = st.PERCENTAGE; String strPercentage = percentage + "%"; String grade = st.GRADE; ((ViewHolder)holder).setData(strID,name,roll_no,strTotal_Marks,strPercentage,grade); Log.d("rogd", "onBindViewHolder: " + position); }
4. 可选:优化Student模型(推荐)
添加完整参数的构造方法,简化对象创建:
public Student(int id, String name, String roll_no, int chemistry, int physics, int math, int total_marks, int percentage, String grade){ this.ID = id; this.NAME = name; this.ROLL_NO = roll_no; this.CHEMISTRY = chemistry; this.PHYSICS = physics; this.MATH = math; this.TOTAL_MARKS = total_marks; this.PERCENTAGE = percentage; this.GRADE = grade; }
内容的提问来源于stack exchange,提问作者Devesh kharade
相关产品推荐
相关产品推荐

