Android Firestore收集数据未显示在回收器视图中,但已正确访问
如标题中所述,我有一个firestore集合,其中包含两个文档,我希望在我的recycler视图中显示它们。我可以在日志中看到数据被正确访问,我的recycler视图适配器大小也显示了正确的数字,但recycler视图没有显示。我认为这可能是因为我使用了视图绑定,但我怀疑这是个问题。我没有主意了,谢谢你的帮助 这是我的RecyclerView适配器:Android Firestore收集数据未显示在回收器视图中,但已正确访问,android,kotlin,google-cloud-firestore,android-recyclerview,Android,Kotlin,Google Cloud Firestore,Android Recyclerview,如标题中所述,我有一个firestore集合,其中包含两个文档,我希望在我的recycler视图中显示它们。我可以在日志中看到数据被正确访问,我的recycler视图适配器大小也显示了正确的数字,但recycler视图没有显示。我认为这可能是因为我使用了视图绑定,但我怀疑这是个问题。我没有主意了,谢谢你的帮助 这是我的RecyclerView适配器: open class BoardItemsAdapter(private val context: Context, private va
open class BoardItemsAdapter(private val context: Context, private val list: ArrayList<Board>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var boardItemClickListener: BoardItemClickInterface? = null;
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding = ItemBoardBinding.inflate(LayoutInflater.from(parent.context),parent,false);
return MyViewHolder(binding);
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = list[position];
if(holder is MyViewHolder){
Glide.with(context)
.load(model.image)
.centerCrop()
.placeholder(R.drawable.ic_board_place_holder)
.into(holder.binding.ivBoardImageItemBoard);
holder.binding.tvNameItemBoard.text = model.name;
holder.binding.tvCreatedByItemBoard.text = "Created by: ${model.createdBy}";
holder.itemView.setOnClickListener {
if(boardItemClickListener != null){
boardItemClickListener!!.onClick(position, model);
}
}
}
}
override fun getItemCount(): Int {
return list.size;
}
inner class MyViewHolder(val binding:ItemBoardBinding):RecyclerView.ViewHolder(binding.root){
}
}
fun populateBoardsListToUI(boardsList: ArrayList<Board>){
mainContentBinding = MainContentBinding.inflate(layoutInflater);
hideProgressDialog();
if(boardsList.size > 0){
mainContentBinding.rvBoards.visibility = View.VISIBLE;
mainContentBinding.tvNoBoardsAvailable.visibility = View.GONE;
mainContentBinding.rvBoards.layoutManager = LinearLayoutManager(this);
mainContentBinding.rvBoards.setHasFixedSize(true);
val adapter = BoardItemsAdapter(this@MainActivity, boardsList);
mainContentBinding.rvBoards.adapter = adapter;
Log.i("POPUI","Board adapter size: ${adapter.itemCount}");
}
else{
mainContentBinding.rvBoards.visibility = View.GONE;
mainContentBinding.tvNoBoardsAvailable.visibility = View.VISIBLE;
}
}
open类BoardItemsAdapter(private-val-context:context,private-val-list:ArrayList):RecyclerView.Adapter(){
私有变量boardItemClickListener:BoardItemClickInterface?=null;
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):RecyclerView.ViewHolder{
val binding=ItemBoardBinding.inflate(LayoutFlater.from(parent.context),parent,false);
返回MyViewHolder(具有约束力);
}
覆盖onBindViewHolder(holder:RecyclerView.ViewHolder,位置:Int){
val模型=列表[位置];
如果(持有人是MyViewHolder){
带(上下文)滑动
.load(model.image)
.centerCrop()
.占位符(R.可绘制ic\U板\U位置\U支架)
.进入(持有人.绑定.ivBoardImageItemBoard);
holder.binding.tvNameItemBoard.text=model.name;
holder.binding.tvCreatedByItemBoard.text=“创建人:${model.createdBy}”;
holder.itemView.setOnClickListener{
如果(boardItemClickListener!=null){
boardItemClickListener!!.onClick(位置、型号);
}
}
}
}
重写getItemCount():Int{
返回列表大小;
}
内部类MyViewHolder(val绑定:ItemBoardBinding):RecyclerView.ViewHolder(binding.root){
}
}
FirestoreClass的一个片段
fun getBoardsList(activity: MainActivity){
mFirestore.collection(Constants.BOARDS)
.whereArrayContains(Constants.ASSIGNED_TO,getCurrentUserID())
.get()
.addOnSuccessListener {
document ->
Log.i(activity.javaClass.simpleName, document.documents.toString()); //logs correct data
val boardList: ArrayList<Board> = ArrayList();
for(i in document.documents){
val board = i.toObject(Board::class.java)!!;
board.documentID = i.id;
boardList.add(board)
}
activity.populateBoardsListToUI(boardList);
}.addOnFailureListener {
e ->
activity.hideProgressDialog();
Log.e(activity.javaClass.simpleName,"Error while creatng a board",e);
}
}
import android.os.Parcel
import android.os.Parcelable
import kotlinx.parcelize.Parceler
import kotlinx.parcelize.Parcelize
@Parcelize
data class Board(
val name: String = "",
val image : String = "",
val createdBy: String = "",
val assignedTo: ArrayList<String> = ArrayList(),
var documentID: String = ""
): Parcelable{
constructor(parcel: Parcel): this(
parcel.readString()!!,
parcel.readString()!!,
parcel.readString()!!,
parcel.createStringArrayList()!!,
parcel.readString()!!
)
override fun describeContents() = 0
companion object : Parceler<Board> {
override fun Board.write(dest: Parcel, flags: Int) = with(dest) {
writeString(name);
writeString(image);
writeString(createdBy);
writeStringList(assignedTo);
writeString(documentID);
}
override fun create(parcel: Parcel): Board = TODO()
}
}
fun getBoardsList(活动:MainActivity){
mFirestore.collection(常量.BOARDS)
.WHERERRAYCONTAINS(常数.分配给,getCurrentUserID())
.get()
.addOnSuccessListener{
文档->
Log.i(activity.javaClass.simpleName,document.documents.toString());//记录正确的数据
val boardList:ArrayList=ArrayList();
对于(文件中的i.documents){
val board=i.toObject(board::class.java)!!;
board.documentID=i.id;
董事会名单。添加(董事会)
}
活动:PopulateBoardListtoui(董事会名单);
}.addOnFailureListener{
e->
activity.hideProgressDialog();
Log.e(activity.javaClass.simpleName,“创建板时出错”,e);
}
}
MainActivity的一个片段:
open class BoardItemsAdapter(private val context: Context, private val list: ArrayList<Board>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var boardItemClickListener: BoardItemClickInterface? = null;
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding = ItemBoardBinding.inflate(LayoutInflater.from(parent.context),parent,false);
return MyViewHolder(binding);
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = list[position];
if(holder is MyViewHolder){
Glide.with(context)
.load(model.image)
.centerCrop()
.placeholder(R.drawable.ic_board_place_holder)
.into(holder.binding.ivBoardImageItemBoard);
holder.binding.tvNameItemBoard.text = model.name;
holder.binding.tvCreatedByItemBoard.text = "Created by: ${model.createdBy}";
holder.itemView.setOnClickListener {
if(boardItemClickListener != null){
boardItemClickListener!!.onClick(position, model);
}
}
}
}
override fun getItemCount(): Int {
return list.size;
}
inner class MyViewHolder(val binding:ItemBoardBinding):RecyclerView.ViewHolder(binding.root){
}
}
fun populateBoardsListToUI(boardsList: ArrayList<Board>){
mainContentBinding = MainContentBinding.inflate(layoutInflater);
hideProgressDialog();
if(boardsList.size > 0){
mainContentBinding.rvBoards.visibility = View.VISIBLE;
mainContentBinding.tvNoBoardsAvailable.visibility = View.GONE;
mainContentBinding.rvBoards.layoutManager = LinearLayoutManager(this);
mainContentBinding.rvBoards.setHasFixedSize(true);
val adapter = BoardItemsAdapter(this@MainActivity, boardsList);
mainContentBinding.rvBoards.adapter = adapter;
Log.i("POPUI","Board adapter size: ${adapter.itemCount}");
}
else{
mainContentBinding.rvBoards.visibility = View.GONE;
mainContentBinding.tvNoBoardsAvailable.visibility = View.VISIBLE;
}
}
fun PopulateBoardListToUI(boardsList:ArrayList){
mainContentBinding=mainContentBinding.充气(更平);
hideProgressDialog();
如果(boardsList.size>0){
mainContentBinding.rvBoards.visibility=View.VISIBLE;
mainContentBinding.tvNoBoardsAvailable.visibility=View.GONE;
mainContentBinding.rvBoards.layoutManager=LinearLayoutManager(此);
mainContentBinding.rvBoards.setHasFixedSize(真);
val适配器=BoardItemsAdapter(this@MainActivity,董事会名单);
mainContentBinding.rvBoards.adapter=适配器;
Log.i(“POPUI”,“板适配器大小:${adapter.itemCount}”);
}
否则{
mainContentBinding.rvBoards.visibility=View.GONE;
mainContentBinding.tvNoBoardsAvailable.visibility=View.VISIBLE;
}
}
MainContent.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="@drawable/ic_background"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/main_screen_content_padding"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.MainActivity">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:elevation="@dimen/card_view_elevation"
app:cardCornerRadius="@dimen/card_view_corner_radius"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_boards"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
/>
<TextView
android:id="@+id/tv_no_boards_available"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/no_boards_available"
android:gravity="center"
android:textColor="@color/secondary_text_color"
android:textSize="@dimen/no_boards_available_text_size"
/>
</androidx.cardview.widget.CardView>
</LinearLayout>
这是否回答了您的问题@androidLearner据我所知,适配器已经从addOnSuccessListener
创建,这相当于链接答案中的onDataChange
。你能解释一下为什么你认为这是重复的吗?因为他正在将活动传递给firestore类,一旦他得到文档,他就会调用activity方法来填充recyclerview。所以我相信,他可以从活动本身调用firestore实例,而不是firestore类。所以我想,如果他看到那个问题和答案,他会从中得到更好的答案。如果我错了,请纠正我。@FrankvanPuffelenThank谢谢你的回答@androidLearner我明白你的意思,但我使用我的FirestoreClass作为一个地方,所有处理访问或创建firestore中数据的方法都是在这里编写的。这样,如果我需要更改某个我知道它在一个地方的内容,我就不必追踪我调用该方法进行更改的类。这就是我不在activity中直接调用firestore实例的原因。是的。您的意图是正确的。但如果您以异步方法传递整个activity,则无法获取数据。因此,如果您了解架构组件,我建议您:,您可以对所有数据库访问代码使用repository类。从数据库获取数据后,使用可变实时数据将数据发送到“活动”。使用观察者概念从firestore回调中获取实时数据@佩罗1