why i am getting same row displayed every time using recycler view?

Viewed 67

Why I am getting same row displayed every time using RecyclerView??

I have created an ArrayList, called studentList, where all data retrieved from database is stored but at time of populating the RecyclerView, only the first row of database get populated multiple times.

//database copied from db file// 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

enter image description here

databaseHelper Class

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 class

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 class

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 class

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);
        }
    }
}
3 Answers

first - Change line from

ViewHolder.setData(strID,name,roll_no,strTotal_Marks,strPercentage,grade);

to

holder.setData(strID,name,roll_no,strTotal_Marks,strPercentage,grade);

second -

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

to

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

third

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

to

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

You should omit static modifier from the data members of the ViewHolder class as it causes you to update the same set of data members every time the onBindViewHolder() is called for each row by Recycler View Adapter.

In your GetStudentData() inside StudentDatabasaeHelper

 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()){

      // Student model should be here 
        Student model = new Student();

     ...// rest of your code 
       
        allStudents.add(model);
    }
    return allStudents;
}

Student model object is created only once outside while loop it should be inside while loop.

Student model = new Student();

What's happening is Student Class object is created and assigned a reference and that same object (named model in your case) is added to the list with different student records when the last student record is added it assign's all the other objects the last student record.

Example

Student model = new Student();

model.ID = 1;
list.add(model)

model.ID = 2;
list.add(model)

model.ID = 3;
list.add(model)

model.ID = 4;
list.add(model)

The size of the list will be 4 but when i will try to iterate and print the model.id it will always give me ID = 4.

Related