Android 尝试使用RecyclerView和Fragments显示我的Firestore数据库中的整个集合-Kotlin

Android 尝试使用RecyclerView和Fragments显示我的Firestore数据库中的整个集合-Kotlin,android,firebase,kotlin,android-recyclerview,google-cloud-firestore,Android,Firebase,Kotlin,Android Recyclerview,Google Cloud Firestore,我已经尝试了很多不同的教程,但都无法将它们与我的应用程序联系起来。我在gist中的应用程序显示用户正在服用的药物。这是我的数据类 import java.util.HashMap class LocalMedication { var m_medicationName: String? = null var m_medicationQty: String? = null var m_medicationType: String? = null var m_med

我已经尝试了很多不同的教程,但都无法将它们与我的应用程序联系起来。我在gist中的应用程序显示用户正在服用的药物。这是我的数据类

import java.util.HashMap

class LocalMedication {
    var m_medicationName: String? = null
    var m_medicationQty: String? = null
    var m_medicationType: String? = null
    var m_medicationExpDate: String? = null
    var m_medicationStatus: Boolean = false

    constructor() {}

    constructor(medicationName: String, medicationQty: String, medicationType: String, medicationExpDat : String, medicationStatus : Boolean) {
        this.m_medicationName = medicationName
        this.m_medicationType = medicationType
        this.m_medicationQty = medicationQty
        this.m_medicationExpDate = medicationExpDat
        this.m_medicationStatus = medicationStatus
    }

    fun toMap(): Map<String, Any> {

        val result = HashMap<String, Any>()
        result.put("medicationName", m_medicationName!!)
        result.put("medicationType", m_medicationType!!)
        result.put("medicationQty", m_medicationQty!!)
        result.put("medicationExpDate", m_medicationExpDate!!)
        result.put("medicationStatus", m_medicationStatus!!)

        return result
    }
}
这是我的片段

class LocalMedication : Fragment() {

    private var adapter: FirestoreRecyclerAdapter<LocalMedication, medicationViewHolder>? = null

    private var firestoreDB: FirebaseFirestore? = null
    private var firestoreListener: ListenerRegistration? = null
    private var medList = mutableListOf<LocalMedication>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(R.layout.activity_main)

        firestoreDB = FirebaseFirestore.getInstance()

        val recyclerView = recyclerview as? RecyclerView

        val mLayoutManager = LinearLayoutManager(context)
        recyclerView?.layoutManager = mLayoutManager
        recyclerView?.itemAnimator = DefaultItemAnimator()

        loadMedication()

        firestoreListener = firestoreDB!!.collection("notes")
            .addSnapshotListener(EventListener { documentSnapshots, e ->
                if (e != null) {
                    Log.e(TAG, "Listen failed!", e)
                    return@EventListener
                }

                medList = mutableListOf()

                if (documentSnapshots != null) {
                    for (doc in documentSnapshots) {
                        val note = doc.toObject(LocalMedication::class.java)
                        note.m_medicationName = doc.id
                        medList.add(note)
                    }
                }

                adapter!!.notifyDataSetChanged()
                recyclerView?.adapter = adapter
            })
    }

    override fun onDestroy() {
        super.onDestroy()

        firestoreListener!!.remove()
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val binding: FragmentLocalMedicationBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_local_medication, container, false)

        binding.viewMedicationButton.setOnClickListener { v: View ->
            v.findNavController().navigate(LocalMedicationDirections.actionLocalMedicationToViewMedication())
        }
        binding.addMedicationButton.setOnClickListener { v: View ->
            v.findNavController().navigate(LocalMedicationDirections.actionLocalMedicationToAddMedication())
        }
        binding.homeButton.setOnClickListener { v: View ->
            v.findNavController().navigate(LocalMedicationDirections.actionLocalMedicationToHome2())
        }
        setHasOptionsMenu(true)

        return binding.root
    }

    private fun loadMedication() {
        val query = firestoreDB!!.collection("notes")

        val response = FirestoreRecyclerOptions.Builder<LocalMedication>()
            .setQuery(query, LocalMedication::class.java)
            .build()

        adapter = object : FirestoreRecyclerAdapter<LocalMedication, medicationViewHolder>(response) {
            override fun onBindViewHolder(holder: medicationViewHolder, position: Int, model: LocalMedication) {
                val note = medList[position]

                holder.medicationName.text = note.m_medicationName
                holder.medicationType.text = note.m_medicationType
                holder.medicationQty.text = note.m_medicationQty
            }

            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): medicationViewHolder {
                val view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.recyclerview_item, parent, false)

                return medicationViewHolder(view)
            }

            override fun onError(e: FirebaseFirestoreException) {
                Log.e("error", e!!.message)
            }
        }

        adapter!!.notifyDataSetChanged()
        recyclerview?.adapter = adapter
    }


    public override fun onStart() {
        super.onStart()

        adapter!!.startListening()
    }

    public override fun onStop() {
        super.onStop()

        adapter!!.stopListening()
    }
}
class-localmedicing:Fragment(){
专用var适配器:FirestoreRecyclerAdapter?=null
私有变量firestoreDB:FirebaseFirestore?=null
私有变量firestoreListener:ListenerRegistration?=null
private var medList=mutableListOf()
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
//setContentView(R.layout.activity_main)
firestoreDB=FirebaseFirestore.getInstance()
val recyclerView=recyclerView as?recyclerView
val mLayoutManager=LinearLayoutManager(上下文)
recyclerView?.layoutManager=mLayoutManager
recyclerView?.itemAnimator=DefaultItemAnimator()
药物治疗
firestoreListener=firestoreDB!!.collection(“注释”)
.addSnapshotListener(EventListener{documentSnapshots,e->
如果(e!=null){
Log.e(标记“侦听失败!”,e)
return@EventListener
}
medList=mutableListOf()
if(documentSnapshots!=null){
用于(文档快照中的文档){
val note=doc.toObject(localmedicing::class.java)
note.m_medicationName=doc.id
medList.add(注)
}
}
适配器!!.notifyDataSetChanged()
recyclerView?.adapter=适配器
})
}
重写onDestroy(){
super.ondestory()
firestoreListener!!.remove()
}
覆盖创建视图(充气机:布局充气机,容器:ViewGroup?,savedInstanceState:Bundle?):视图{
val绑定:FragmentLocalMedicinationBinding=DataBindingUtil.充气(充气器,R.layout.fragment\u local\u药物,容器,false)
binding.viewMedicationButton.setOnClickListener{v:View->
v、 findNavController().导航(LocalMedicinationDirections.ActionLocalMedicinationToViewMedicing())
}
binding.addMedicationButton.setOnClickListener{v:View->
v、 findNavController().导航(LocalMedicinationDirections.ActionLocalMedicinationToAddMedicing())
}
binding.homeButton.setOnClickListener{v:View->
v、 findNavController().导航(LocalMedicalationDirections.ActionLocalMedicalationToHome2())
}
设置选项菜单(真)
返回binding.root
}
私人娱乐{
val query=firestoreDB!!.collection(“注释”)
val响应=FirestoreRecyclerOptions.Builder()
.setQuery(查询,localmedicing::class.java)
.build()
适配器=对象:FirestoreRecyclerAdapter(响应){
覆盖BindViewHolder(holder:MedicinationViewHolder,位置:Int,型号:LocalMedicing){
val note=medList[位置]
holder.medicationName.text=note.m_medicationName
holder.medicationType.text=note.m_medicationType
holder.medicationQty.text=note.m\u medicationQty
}
重写CreateViewHolder(父级:ViewGroup,viewType:Int):MedicalationViewHolder{
val view=LayoutInflater.from(parent.context)
.充气(R.layout.recyclerview_项目,父项,假)
返回药物视图支架(视图)
}
重写错误(e:FirebaseFirestoreException){
Log.e(“错误”,e!!.message)
}
}
适配器!!.notifyDataSetChanged()
recyclerview?.adapter=适配器
}
public override fun onStart(){
super.onStart()
适配器!!.startListening()
}
公共覆盖乐趣桌面(){
super.onStop()
适配器!!.stopListening()
}
}
这是我的RecycleServiceItemXML文件

<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:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/rv_medicationName"
            style="@style/word_title"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:background="@android:color/holo_orange_light"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/rv_medicationQty"
            style="@style/word_title"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_orange_light"
            app:layout_constraintStart_toEndOf="@+id/rv_medicationName"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/rv_medicationType"
            style="@style/word_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:background="@android:color/holo_orange_light"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/rv_medicationQty"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>


任何帮助或指导都会很好。它运行应用程序,但在日志中显示“RecyclerView:未连接适配器;跳过布局”

代码中的问题在于
LocalMedicing
类中字段的名称与数据库中属性的名称不同。您的
LocalMedicing
中有一个名为
m_MedicinationName
的a类字段,而在您的数据库中,我将其视为
MedicinationName
,这是不正确的。名称必须匹配。在幕后,Kotlin正在使用名为
getM_MedicalationName()
的getter创建一个Java类,因此Firebase正在数据库中查找名为
m_MedicalationName
MedicalationName
的字段

有两种方法可以解决这个问题。第一种方法是删除数据库中的数据,并使用
localmedicing
类中存在的字段名(
m_medicinationname
m_medicinationqty
等)再次添加数据

如果不允许使用第一种解决方案,则第二种方法是在公共字段前面使用
注释。因此,您应该在每个字段前面使用注释。因此,在
localmedicing
类中,字段应如下所示:

@get:PropertyName("medicationName")
@set:PropertyName("medicationName")
public var m_medicationName: String? = null
正如我在以下帖子的回答中所解释的:


它适用于Firebase实时数据库,但同样的规则适用于Cloud Firestore。

代码中的问题在于
LocalMedicing
类中字段的名称与数据库中属性的名称不同。您的
LocalMedicing
a类
<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"
    tools:context=".LocalMedication">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="32dp"
            android:layout_marginBottom="32dp"
            android:text="LOCAL MEDICATION"
            android:textSize="36sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.478"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="543dp"
            android:layout_height="0dp"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"
            android:background="@android:color/darker_gray"
            app:layout_constraintBottom_toTopOf="@+id/homeButton"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView"
            tools:listitem="@layout/recyclerview_item" />

        <Button
            android:id="@+id/viewMedicationButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="100dp"
            android:layout_marginBottom="100dp"
            android:text="View Med"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

        <Button
            android:id="@+id/addMedicationButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="100dp"
            android:layout_marginBottom="100dp"
            android:text="Add Medication"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Button
            android:id="@+id/homeButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="30dp"
            android:layout_marginTop="59dp"
            android:layout_marginEnd="30dp"
            android:layout_marginBottom="103dp"
            android:text="Home"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/viewMedicationButton"
            app:layout_constraintStart_toEndOf="@+id/addMedicationButton"
            app:layout_constraintTop_toBottomOf="@+id/addMedicationButton"
            app:layout_constraintVertical_bias="0.972" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>
@get:PropertyName("medicationName")
@set:PropertyName("medicationName")
public var m_medicationName: String? = null