Home > Blockchain >  App crash on recyclerview scrolling android kotlin
App crash on recyclerview scrolling android kotlin

Time:12-24

I'm working on a project dealing with loading data from firebase into recyclerview. recyclerview seems working just fine but when i try to scroll it until the end of the posts it always make the app crash. it's so strange to me if i don't scroll to the end post it won't crash. in logcat it show only an error "fail to acquire dataanalyzer...". i have no clue about it. please kindly help!

Code as below :

package teacher

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.amazontutoringcenter.R
import com.example.amazontutoringcenter.databinding.ActivityTeacherLessonPlanBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.*
import com.google.firebase.firestore.EventListener
import com.squareup.picasso.Picasso
import student.StudentPostData
import kotlin.collections.ArrayList

class TeacherLessonPlan: AppCompatActivity() {

    private lateinit var binding : ActivityTeacherLessonPlanBinding
    private lateinit var auth: FirebaseAuth
    private lateinit var firebaseFirestore: FirebaseFirestore
    private lateinit var userRecyclerview: RecyclerView
    private lateinit var studentLessonPlanAdapter: LessonPlanAdapter
    private lateinit var userArrayList: ArrayList<StudentPostData>
    private lateinit var studentName: String
    private lateinit var studentProfileUri : String

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        binding = ActivityTeacherLessonPlanBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        auth = FirebaseAuth.getInstance()

        // post lesson plan

        binding.tvStudentName.setOnClickListener {

                intent = Intent(this, TeacherLessonPlanPost::class.java)
                intent.putExtra("studentName", studentName)
                intent.putExtra("studentProfileUri", studentProfileUri)
                startActivity(intent)
        }

            // get passing data to display profile and name
            var b: Bundle = intent.extras!!
            studentProfileUri = b.getString("studentProfileUri").toString()
            studentName = b.getString("studentName").toString()
            Picasso.get().load(studentProfileUri).fit()
                .centerCrop().into(binding.imageStudentProfile)


            userRecyclerview = findViewById(R.id.recyclerViewStudentLessonPlan)
            userRecyclerview.layoutManager = LinearLayoutManager(this)

            userArrayList = arrayListOf()
            studentLessonPlanAdapter = LessonPlanAdapter(userArrayList)
            userRecyclerview.adapter = studentLessonPlanAdapter

        getStudentLessonPlanPost()

    }

    private fun getStudentLessonPlanPost() {
        val uid = auth.currentUser!!.uid
        firebaseFirestore = FirebaseFirestore.getInstance()
        firebaseFirestore.collection("student").document("lesson plan")
            .collection("$uid")
            .addSnapshotListener(object : EventListener<QuerySnapshot> {
                override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                    if(error != null){
                        Log.d("check error", error.message.toString())
                        return
                    }

                    for(dc : DocumentChange in value?.documentChanges!!){

                        if(dc.type == DocumentChange.Type.ADDED){

                            userArrayList.add(dc.document.toObject(StudentPostData::class.java))
                            userArrayList.sortByDescending {
                                it.date
                            }
                        }
                    }

                    studentLessonPlanAdapter.notifyDataSetChanged()
                }

            })

    }

    inner class LessonPlanAdapter(private val userList : ArrayList<StudentPostData>) : RecyclerView.Adapter<LessonPlanAdapter.MyViewHolder>() {


        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

            val itemView = LayoutInflater.from(parent.context).inflate(
                R.layout.student_lesson_plan,
                parent,false)
            return MyViewHolder(itemView)

        }

        override fun getItemCount(): Int {

            return userList.size
        }

        inner class MyViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){

            val txLessonPlanDescription : TextView = itemView.findViewById(R.id.txLessonPlanDescription)
            val imageStudentLessonPlan : ImageView = itemView.findViewById(R.id.imageStudentLessonPlan)

            val imageStudentProfilePost : ImageView = itemView.findViewById(R.id.imageStudentProfilePost)
            val tvStudentNamePost : TextView = itemView.findViewById(R.id.tvStudentNamePost)

            // date on the post
            val textDate : TextView = itemView.findViewById(R.id.txLessonPlanDate)

        }

        override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

            val currentitem = userList[position]

            holder.txLessonPlanDescription.text = currentitem.description
            holder.textDate.text = currentitem.date
            Picasso.get().load(currentitem.imageUri)
                .into(holder.imageStudentLessonPlan)

            holder.tvStudentNamePost.text = studentName
            Picasso.get().load(studentProfileUri).fit()
                .centerCrop().into(holder.imageStudentProfilePost)

        }

    }

}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">

    <LinearLayout
        android:id="@ id/relativeLayout"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:padding="15dp"
        android:elevation="10dp"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="5dp">

        <com.google.android.material.imageview.ShapeableImageView
            android:id="@ id/imageStudentProfile"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginStart="5dp"
            android:layout_marginTop="50dp"
            android:src="@drawable/ic_profile"
            app:shapeAppearanceOverlay="@style/circular"
            app:strokeColor="#0AF3D0"
            android:layout_gravity="center_horizontal"
            app:strokeWidth="1dp" />

        <TextView
            android:id="@ id/tvStudentName"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginLeft="10dp"
            android:padding="5dp"
            android:fontFamily="serif"
            android:clickable="true"
            android:hint="បង្ហោះកិច្ចតែងការបង្រៀន..."
            android:background="@drawable/border_square"
            android:textColor="#2196F3"
            android:textSize="20dp" />

    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@ id/recyclerViewStudentLessonPlan"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/student_lesson_plan">

    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

CodePudding user response:

Since you are using the userArrayList variable globally to serve your adapter the data try to remove the LessonPlanAdapter class parameter and just use the global variable to populate it:

inner class LessonPlanAdapter() : RecyclerView.Adapter<LessonPlanAdapter.MyViewHolder>() {

    ...

    override fun getItemCount(): Int = userArrayList.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val currentitem = userArrayList[position]
            
        ...
    }
}

I think that the problem may be related to the fact that the class variable containing the data wasn't updated correctly.

That could have caused an index out of bounds exception when reaching the bottom of the list.

CodePudding user response:

Solved ! I'm not sure what the problem was but I could solve it by deleting all of the documents that I have in firestore then trying to add new documents. now it's working fine. thank guys for your help !

  • Related