Android 尝试使用RecyclerView和Fragments显示我的Firestore数据库中的整个集合-Kotlin
我已经尝试了很多不同的教程,但都无法将它们与我的应用程序联系起来。我在gist中的应用程序显示用户正在服用的药物。这是我的数据类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
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