如何将Firestore返回的$document.data转换为可用于ListView的可用格式
实现方案
步骤1:创建匹配Firestore字段的Kotlin数据实体类
先定义和返回字段完全对应的实体类,后续所有逻辑都可以直接用该类的对象操作,复用性最高:
import com.google.firebase.firestore.PropertyName import androidx.annotation.Keep @Keep // 防止混淆导致字段映射失败 data class User( var id: String = "", var lastName: String = "", var firstName: String = "", var image: String = "", var gender: String = "", var organization: String = "", var profileCompleted: Int = 0, var mobile: Long = 0, // 字段带空格需要用PropertyName指定映射的字段名 @PropertyName("blood group") var bloodGroup: String = "", var email: String = "", var B: String = "" )
注意所有字段都要设置默认值,否则Firestore映射的时候会抛出异常。
步骤2:修改查询回调,将DocumentSnapshot转换为实体类对象
修改你原来的成功回调逻辑,把查询到的文档转成User对象,存入列表供后续使用:
// 先定义存储查询结果的全局列表 private val userList = mutableListOf<User>() private val mFireStore = FirebaseFirestore.getInstance() mFireStore.collection("Users") .whereEqualTo("lastName","H") .whereEqualTo("firstName", "Uc") .get() .addOnSuccessListener{ documents -> // 先清空旧数据避免重复 userList.clear() for(document in documents){ // 核心转换逻辑,直接把document映射为User对象 val user = document.toObject(User::class.java) userList.add(user) Log.d("TAG","${user.id}=>${user.email}") } // 数据获取完成后,通知ListView刷新 userAdapter.notifyDataSetChanged() Toast.makeText(applicationContext, "查询到${userList.size}条数据", Toast.LENGTH_LONG).show() } .addOnFailureListener{exception -> Log.w("TAG","Error getting documents:",exception) Toast.makeText(applicationContext, "获取数据失败", Toast.LENGTH_LONG).show() }
步骤3:实现ListView的自定义适配器
你可以根据自己的布局需求实现适配器,示例代码如下:
class UserAdapter(context: Context, private val dataList: List<User>) : BaseAdapter() { private val inflater = LayoutInflater.from(context) override fun getCount(): Int = dataList.size override fun getItem(position: Int): Any = dataList[position] override fun getItemId(position: Int): Long = position.toLong() override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view: View val viewHolder: ViewHolder if (convertView == null) { // 替换为你自己的列表项布局 view = inflater.inflate(R.layout.item_user, parent, false) viewHolder = ViewHolder(view) view.tag = viewHolder } else { view = convertView viewHolder = view.tag as ViewHolder } val user = dataList[position] // 给控件赋值,替换为你自己的控件ID viewHolder.tvName.text = "${user.firstName} ${user.lastName}" viewHolder.tvEmail.text = user.email viewHolder.tvBloodGroup.text = user.bloodGroup return view } class ViewHolder(itemView: View) { // 替换为你自己布局里的控件 val tvName: TextView = itemView.findViewById(R.id.tv_name) val tvEmail: TextView = itemView.findViewById(R.id.tv_email) val tvBloodGroup: TextView = itemView.findViewById(R.id.tv_blood_group) } }
步骤4:绑定适配器到ListView
在Activity的onCreate方法里提前初始化适配器并绑定到ListView:
// 全局变量 private lateinit var userAdapter: UserAdapter // onCreate里执行 userAdapter = UserAdapter(this, userList) // 替换为你布局里的ListView ID listView.adapter = userAdapter
完成以上步骤后,每次查询到新数据都会自动刷新ListView显示内容,同时userList里的User对象可以直接在其他业务逻辑里复用。
内容的提问来源于stack exchange,提问作者user15880034
相关产品推荐
相关产品推荐

