如何为RecyclerView添加编辑删除按钮逻辑以操作Firebase实时数据库
问题描述
我是编程初学者,若代码不够规整请见谅,我需要帮助完成我的程序。
我使用RecyclerView从实时数据库拉取数据,希望在RecyclerView中添加编辑和删除按钮,实现数据的编辑、删除操作。
我已经在XML文件中创建了按钮,仅不清楚如何编写按钮的逻辑代码。我尝试过相关教程、参考过其他帖子的代码,但多数情况下要么代码报错,要么点击按钮无任何反应。我已将代码和数据库结构附在下方:
现有代码
DoctorViewAdapter.kt
package com.example.patientmonitor import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.webkit.WebView import android.webkit.WebViewClient import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.android.volley.Request import com.android.volley.Response import com.android.volley.toolbox.StringRequest import com.android.volley.toolbox.Volley import java.util.ArrayList import kotlin.concurrent.fixedRateTimer class DoctorViewAdapter(private val patientList : ArrayList<doctorViewPatient>) : RecyclerView.Adapter<DoctorViewAdapter.DoctorViewHolder>() { //WebView private lateinit var pulseGraph: WebView private lateinit var temperatureGraph: WebView override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DoctorViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.patient_item,parent,false) return DoctorViewHolder(itemView) pulseGraph.webViewClient = WebViewClient() temperatureGraph.webViewClient = WebViewClient() pulseGraph.settings.javaScriptEnabled = true temperatureGraph.settings.javaScriptEnabled = true pulseGraph.settings.builtInZoomControls = true temperatureGraph.settings.builtInZoomControls = true } override fun onBindViewHolder(holder: DoctorViewHolder, position: Int) { val currentitem = patientList[position] holder.userID.text = currentitem.userID holder.fullName.text = currentitem.fullName holder.userEmail.text = currentitem.email holder.phoneNumber.text = currentitem.phoneNumber var pulseValue = "null" var temperatureValue = "null" //get pulse value from thingspeak and set to text view val pulsequeue = Volley.newRequestQueue(holder.pulseValue.context) val temperaturequeue = Volley.newRequestQueue(holder.temperatureValue.context) val pulseRequest = StringRequest(Request.Method.GET, currentitem.pulseValue as String?, Response.Listener<String> { response -> pulseValue = response holder.pulseValue.text = pulseValue }, Response.ErrorListener { // didn't work }) //get temperature value from thingspeak and set to text view val tempRequest = StringRequest(Request.Method.GET, currentitem.temperatureValue as String?, Response.Listener<String> { response -> temperatureValue = response holder.temperatureValue.text = temperatureValue }, Response.ErrorListener { // didn't work }) //get thingspeak data every 1 second fixedRateTimer("timer", false, 0L, 1000) { pulsequeue.add(pulseRequest) temperaturequeue.add(tempRequest) } } override fun getItemCount(): Int { return patientList.size } class DoctorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){ val userID : TextView = itemView.findViewById(R.id.tvUserID) val fullName : TextView = itemView.findViewById(R.id.tvFullName) val userEmail : TextView = itemView.findViewById(R.id.tvEmail) val phoneNumber : TextView = itemView.findViewById(R.id.tvPhoneNumber) val pulseValue : TextView = itemView.findViewById(R.id.tvPulseValue) val temperatureValue : TextView = itemView.findViewById(R.id.tvTemperatureValue) } }
PatientlistActivity.kt
package com.example.patientmonitor import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.webkit.WebView import androidx.appcompat.app.ActionBar import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.firebase.database.* class PatientListActivity : AppCompatActivity() { private lateinit var dbref : DatabaseReference private lateinit var userRecyclerview : RecyclerView private lateinit var userArrayList : ArrayList<doctorViewPatient> private lateinit var viewPatientBtn : FloatingActionButton private lateinit var doctorViewAdapter : DoctorViewAdapter //ActionBar private lateinit var actionBar: ActionBar //WebView private lateinit var pulseView: WebView private lateinit var tempView: WebView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_patient_list) //configure Actionbar //enable back button actionBar = supportActionBar!! actionBar.title = "View Patients" actionBar.setDisplayHomeAsUpEnabled(true) actionBar.setDisplayShowHomeEnabled(true) userRecyclerview = findViewById(R.id.patientList) userRecyclerview.layoutManager = LinearLayoutManager(this) userRecyclerview.setHasFixedSize(true) userArrayList = arrayListOf<doctorViewPatient>() getUserData() } private fun getUserData() { //get intent val assignedDoctor = intent.getStringExtra("doctorID") val currentUserAccess = intent.getStringExtra("currentUserAccess") dbref = FirebaseDatabase.getInstance().getReference("Users") dbref.orderByChild("assignedDoctor").equalTo(assignedDoctor).addListenerForSingleValueEvent(object : ValueEventListener{ override fun onDataChange(snapshot: DataSnapshot) { if (snapshot.exists()){ for (userSnapshot in snapshot.children){ val user = userSnapshot.getValue(doctorViewPatient::class.java) userArrayList.add(user!!) } userRecyclerview.adapter = DoctorViewAdapter(userArrayList) } } override fun onCancelled(error: DatabaseError) { TODO("Not yet implemented") } }) } }
doctorViewPatient.kt
data class doctorViewPatient(val userID : String? =null, val fullName : String? =null, val email : String? =null, val phoneNumber : String? =null, val pulseValue : String? = null, val temperatureValue : String? = null)
实现方案
我们通过Adapter回调接口的方式实现按钮逻辑,具体修改如下:
1. 修改DoctorViewAdapter
首先在Adapter内添加点击事件回调接口,修改构造函数传入监听器,同时给按钮绑定点击事件:
class DoctorViewAdapter( private val patientList : ArrayList<doctorViewPatient>, // 新增监听器参数 private val listener: OnItemClickListener ) : RecyclerView.Adapter<DoctorViewAdapter.DoctorViewHolder>() { // 新增回调接口 interface OnItemClickListener { fun onEditClick(patient: doctorViewPatient, position: Int) fun onDeleteClick(patient: doctorViewPatient, position: Int) } // 原有WebView代码是无效代码,return之后不会执行,可直接删除 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DoctorViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.patient_item,parent,false) return DoctorViewHolder(itemView) } override fun onBindViewHolder(holder: DoctorViewHolder, position: Int) { val currentitem = patientList[position] // 原有赋值逻辑不变 holder.userID.text = currentitem.userID holder.fullName.text = currentitem.fullName holder.userEmail.text = currentitem.email holder.phoneNumber.text = currentitem.phoneNumber // 原有请求温脉数据逻辑不变,此处省略 // ... // 新增按钮点击事件绑定 holder.btnEdit.setOnClickListener { listener.onEditClick(currentitem, position) } holder.btnDelete.setOnClickListener { listener.onDeleteClick(currentitem, position) } } override fun getItemCount(): Int { return patientList.size } class DoctorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){ // 原有控件引用不变 val userID : TextView = itemView.findViewById(R.id.tvUserID) val fullName : TextView = itemView.findViewById(R.id.tvFullName) val userEmail : TextView = itemView.findViewById(R.id.tvEmail) val phoneNumber : TextView = itemView.findViewById(R.id.tvPhoneNumber) val pulseValue : TextView = itemView.findViewById(R.id.tvPulseValue) val temperatureValue : TextView = itemView.findViewById(R.id.tvTemperatureValue) // 新增按钮引用,ID和你XML里定义的保持一致即可 val btnEdit: View = itemView.findViewById(R.id.btnEdit) val btnDelete: View = itemView.findViewById(R.id.btnDelete) } }
2. 修改PatientListActivity
让Activity实现回调接口,处理编辑删除的数据库操作和界面刷新:
// 实现Adapter的OnItemClickListener接口 class PatientListActivity : AppCompatActivity(), DoctorViewAdapter.OnItemClickListener { private lateinit var dbref : DatabaseReference private lateinit var userRecyclerview : RecyclerView private lateinit var userArrayList : ArrayList<doctorViewPatient> private lateinit var doctorViewAdapter : DoctorViewAdapter private lateinit var actionBar: ActionBar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_patient_list) actionBar = supportActionBar!! actionBar.title = "View Patients" actionBar.setDisplayHomeAsUpEnabled(true) actionBar.setDisplayShowHomeEnabled(true) userRecyclerview = findViewById(R.id.patientList) userRecyclerview.layoutManager = LinearLayoutManager(this) userRecyclerview.setHasFixedSize(true) userArrayList = arrayListOf() dbref = FirebaseDatabase.getInstance().getReference("Users") getUserData() } private fun getUserData() { val assignedDoctor = intent.getStringExtra("doctorID") dbref.orderByChild("assignedDoctor").equalTo(assignedDoctor).addListenerForSingleValueEvent(object : ValueEventListener{ override fun onDataChange(snapshot: DataSnapshot) { if (snapshot.exists()){ userArrayList.clear() for (userSnapshot in snapshot.children){ val user = userSnapshot.getValue(doctorViewPatient::class.java) userArrayList.add(user!!) } // 初始化Adapter时传入当前Activity作为监听器 doctorViewAdapter = DoctorViewAdapter(userArrayList, this@PatientListActivity) userRecyclerview.adapter = doctorViewAdapter } } override fun onCancelled(error: DatabaseError) {} }) } // 编辑逻辑实现 override fun onEditClick(patient: doctorViewPatient, position: Int) { // 此处可替换为你自己的编辑逻辑,比如弹输入框获取修改后的值 val updateData = mapOf( "fullName" to "修改后的姓名", "phoneNumber" to "修改后的手机号" // 其他需要修改的字段按需添加 ) dbref.child(patient.userID!!).updateChildren(updateData).addOnSuccessListener { // 更新本地列表刷新界面 val updatedPatient = patient.copy( fullName = updateData["fullName"] as String, phoneNumber = updateData["phoneNumber"] as String ) userArrayList[position] = updatedPatient doctorViewAdapter.notifyItemChanged(position) } } // 删除逻辑实现 override fun onDeleteClick(patient: doctorViewPatient, position: Int) { dbref.child(patient.userID!!).removeValue().addOnSuccessListener { // 移除本地数据刷新界面 userArrayList.removeAt(position) doctorViewAdapter.notifyItemRemoved(position) } } }
内容的提问来源于stack exchange,提问作者Azri Danial
相关产品推荐
相关产品推荐

