You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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);
        }
    }
}

问题根源与修复方案

核心问题

  1. 数据库查询复用同一对象:GetStudentData方法中,Student实例创建在循环外部,每次循环仅更新该对象属性并添加到集合,导致集合内所有元素指向同一对象,最终显示的是最后一次赋值的数据(或因引用问题显示重复条目)。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:03:34