Как из Firebase добавить данные в RecyclerView
Столкнулся с такой проблемой! Делаю приложение и сейчас мне нужно добавить два разных recyclerview в разные активити. Данные берутся из Firebase.
На первое активити я сделал - все ок. Данные отображаются как нужно, а вот на втором проблема. Мне нужно добавить другие данные, но ошибка java.lang.NullPointerException: workout_title must not be null Знаю, что нужно их инициализировать, но можете подсказать как правильно это сделать и реализовать в проекте?
Код: HomeActivity
package com.skreep.worko
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.database.*
import com.skreep.worko.adapter.WorkoutAdapter
import com.skreep.worko.model.WorkoutData
import kotlinx.android.synthetic.main.activity_detail.*
import kotlinx.android.synthetic.main.activity_home.*
class HomeActivity : BaseActivity() {
lateinit var mDataBase: DatabaseReference
private lateinit var workoutList: ArrayList<WorkoutData>
private lateinit var mAdapter: WorkoutAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
workoutList = ArrayList()
mAdapter = WorkoutAdapter(this, workoutList)
recyclerworkoutList.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
recyclerworkoutList.setHasFixedSize(true)
recyclerworkoutList.adapter = mAdapter
getWorkoutData()
}
private fun getWorkoutData() {
mDataBase = FirebaseDatabase.getInstance().getReference("Workout")
mDataBase.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
for (userSnapshot in snapshot.children) {
val workout = userSnapshot.getValue(WorkoutData::class.java)
workoutList.add(workout!!)
}
recyclerworkoutList.adapter = mAdapter
}
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(this@HomeActivity,
error.message, Toast.LENGTH_SHORT).show()
}
})
}
}
DetailActivity
package com.skreep.worko
import android.content.Intent
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_detail.*
import kotlinx.android.synthetic.main.item_workout_detail.*
class DetailActivity() : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
val workoutIntent = intent
val name = workoutIntent.getStringExtra("name")
val description = workoutIntent.getStringExtra("description")
val workoutName = workoutIntent.getStringExtra("workoutName")
detail_name.text = name
detail_desc.text = description
workout_title.text = workoutName
back_ic.setOnClickListener {
val intent = Intent(this, HomeActivity::class.java)
startActivity(intent)
}
}
}
Adapter
package com.skreep.worko.adapter
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.skreep.worko.DetailActivity
import com.skreep.worko.R
import com.skreep.worko.databinding.ItemWorkoutBinding
import com.skreep.worko.databinding.ItemWorkoutDetailBinding
import com.skreep.worko.model.WorkoutData
class WorkoutAdapter(var c: Context, var workoutList: ArrayList<WorkoutData>
) : RecyclerView.Adapter<WorkoutAdapter.WorkoutViewHolder>() {
inner class WorkoutViewHolder(var v: ItemWorkoutBinding) : RecyclerView.ViewHolder(v.root) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
val inflter = LayoutInflater.from(parent.context)
val v = DataBindingUtil.inflate<ItemWorkoutBinding>(
inflter, R.layout.item_workout, parent,
false)
return WorkoutViewHolder(v)
}
override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
val newList = workoutList[position]
holder.v.isWorkouts = workoutList[position]
holder.v.root.setOnClickListener {
val name = newList.name
val description = newList.description
val fullTime = newList.fullTime
val workoutDesc = newList.workoutDesc
val workoutName = newList.workoutName
val workoutTime = newList.workoutTime
val mIntent = Intent(c, DetailActivity::class.java)
mIntent.putExtra("description", description)
mIntent.putExtra("name", name)
mIntent.putExtra("fullTime", fullTime)
mIntent.putExtra("workoutDesc", workoutDesc)
mIntent.putExtra("workoutName", workoutName)
mIntent.putExtra("workoutTime", workoutTime)
c.startActivity(mIntent)
}
}
override fun getItemCount(): Int {
return workoutList.size
}
}
xml home
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="isWorkouts"
type="com.skreep.worko.model.WorkoutData" />
</data>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkblue"
android:orientation="vertical"
tools:context=".HomeActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:fontFamily="@font/poppins"
android:gravity="center"
android:padding="20dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="20sp" />
<TextView
android:id="@+id/welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:text="@string/welcome"
android:textColor="@color/white"
android:textSize="30sp"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/welcome_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/poppins"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:text="@string/welcome_description"
android:textColor="@color/desc_color"
android:textSize="14sp"
app:layout_constraintTop_toBottomOf="@id/welcome" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerworkoutList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal"
android:paddingTop="40dp"
tools:itemCount="1"
tools:listitem="@layout/item_workout" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</layout>
xml detail
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="isWorkout"
type="com.skreep.worko.model.WorkoutData" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray"
tools:context=".DetailActivity">
<ImageView
android:id="@+id/back_ic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="20dp"
android:padding="20dp"
android:src="@drawable/ic_back">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_margin="20dp"
android:fontFamily="@font/poppins"
android:padding="20dp"
android:text="@string/app_name"
android:textSize="20sp"></TextView>
<TextView
android:id="@+id/detail_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="120dp"
android:fontFamily="@font/poppins_bold"
android:text="@{isWorkout.name}"
android:textColor="@color/darkblue"
android:textSize="26sp"></TextView>
<TextView
android:id="@+id/detail_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/detail_name"
android:layout_alignLeft="@+id/detail_name"
android:fontFamily="@font/poppins"
android:text="@{isWorkout.workoutDesc}"
android:textColor="@color/lightgray">
</TextView>
<TextView
android:id="@+id/tv_workout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="310dp"
android:fontFamily="@font/poppins_bold"
android:gravity="center"
android:text="Упражнения"
android:textColor="@color/darkblue"
android:textSize="20sp"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_workout"
android:orientation="vertical"
android:padding="10dp"
tools:itemCount="1"
tools:listitem="@layout/item_workout_detail"
>
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
</layout>
Ответы (1 шт):
Автор решения: Ким Денис
→ Ссылка
В моём случае так:
User class
data class User(
val fullName: String? = null,
val email: String? = null )
Adapter
class MyAdapter(var list: ArrayList<User>): RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.read_item, parent, false))
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentUser = list[position]
with(holder.itemView) {
get_Fullname_tv.text = currentUser.fullName
get_Email_tv.text = currentUser.email
}
}
override fun getItemCount(): Int {
return list.size
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}
MainActivity
// поля
private lateinit var database: FirebaseDatabase
private lateinit var mRef: DatabaseReference
//метод для получения данных в RecyclerView. (При клике на кнопку)
database = FirebaseDatabase.getInstance()
mRef = database.getReference("Users")
getData_button.setOnClickListener {
val postListener = object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
val list = ArrayList<User>()
for (ds in snapshot.children){
val user = ds.getValue(User::class.java)
list.add(user as User)
}
if (list.size > 0) {
val adapter = MyAdapter(list)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(applicationContext)
}
}
override fun onCancelled(error: DatabaseError) {
Log.d("ValEvenLisLog", error.toString())
}
}
mRef.addValueEventListener(postListener)
}