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 !