I want to populate a RecyclerView with data from Firebase. I tried something, I built an Adapter and tried to populate the RecyclerView but not showing any data in the RecyclerView and I get no errors.
In firebase console shows like the query is working but in the simulator not show anything and i dont ger errors.
[![The Recyclerview from the simulator][1]][1]
My layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CamionesActivos">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/rvCamioness"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="7dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="7dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/tarjeta_recycler" />
</androidx.constraintlayout.widget.ConstraintLay
my adapter:
class AdaptadorCamiones(private val camionlist:ArrayList<datos>)
:RecyclerView.Adapter<AdaptadorCamiones.MyViewHolder>() {
class MyViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
val placa :TextView?=itemView.findViewById(R.id.tvPlacaDato)
val peso: TextView?=itemView.findViewById(R.id.tvPesoDato)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView=
LayoutInflater.from(parent.context).inflate(R.layout.activity_camiones_activos,parent,false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.placa?.text ?: camionlist[position].Placa
holder.peso?.text ?: camionlist[position].Peso
}
override fun getItemCount(): Int {
return camionlist.size
}
}
my activity:
class CamionesActivos : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var camionList: ArrayList<datos>
private var db=Firebase.firestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camiones_activos)
recyclerView=findViewById(R.id.rvCamioness)
recyclerView.layoutManager=LinearLayoutManager(this, LinearLayoutManager.VERTICAL ,false)
camionList= arrayListOf()
recyclerView.adapter = AdaptadorCamiones(camionList)
db=FirebaseFirestore.getInstance()
db.collection("Camiones")
.get()
.addOnSuccessListener {
if(!it.isEmpty){
for (data in it.documents){
val camion: datos? =data.toObject(datos::class.java)
if (camion !=null){
camionList.add(camion)
}
}
}
}
.addOnFailureListener{
Toast.makeText(this, it.toString(), Toast.LENGTH_SHORT).show()
}
}
}```
[1]: https://i.stack.imgur.com/6xmfX.png
CodePudding user response:
The reason why data isn't displaying is because the RecyclerView's adapter (AdaptadorCamiones) isn't aware that it's dataset (camionList) has been updated. Whenever you insert data into the collection that backs the RecyclerView's adapter you need to inform it that a change by calling one of it's many notify...(...) methods. The quick and dirty solution would be to call notifyDataSetChanged() and it will trigger the RecyclerView to be redrawn and you're new data will be at the bottom of the list.
The proper solution would be to use the of the adapters notifyItemInserted(int) overload. This method will inform the adapter that a single item was inserted at the given position. The adapter will trigger the RecyclerView to efficiently update and animate the new item into the specified position.
Calling notifyDataSetChanged() will force the RecyclerView's layout manager to rebind all view and relayout all visible items. Unless you're using stable IDs the RecycleView will not animate any structural changes using this method. Using the more specific notify... overloads will always be more efficient. There are overloads for notify the adapter of several items being inserted, as well as the reciprocal methods for removing one or many items. There are also overloads to notify the adapter of that items have been updated or swapped positions. By calling this overloads instead of notifyDataSetChanged() the RecyclerView will be able to animate the structural changes.
CodePudding user response:
@cincy_anddeveloper
i changed the main code using notifyItemInserted(position) but noting happens and the console shows a error
main code:
class CamionesActivos : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var camionList: ArrayList<datos>
private lateinit var adapter: AdaptadorCamiones
private lateinit var linearLayoutManager: LinearLayoutManager
private var db=Firebase.firestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camiones_activos)
recyclerView=findViewById(R.id.rvCamioness)
linearLayoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = linearLayoutManager
//recyclerView.layoutManager=LinearLayoutManager(this,
LinearLayoutManager.VERTICAL ,false)
camionList= arrayListOf()
adapter= AdaptadorCamiones(camionList)
recyclerView.adapter=adapter
db=FirebaseFirestore.getInstance()
db.collection("Camiones")
.get()
.addOnSuccessListener {
if(!it.isEmpty){
for (data in it.documents){
val camion: datos? =data.toObject(datos::class.java)
if (camion !=null){
camionList.add(camion)
adapter.notifyItemInserted(camionList.size 1)
}
}
}
}
.addOnFailureListener{
Toast.makeText(this, it.toString(), Toast.LENGTH_SHORT).show()
}
}
}
Console error:
E/RecyclerView: No adapter attached; skipping layout