【问题标题】:Kotlin: How to use RecycleView + ViewAdapter so that different users get different ViewHolders?Kotlin:如何使用 RecyclerView + View Adapter 让不同的用户得到不同的 ViewHolders?
【发布时间】:2020-01-12 15:00:14
【问题描述】:

我正在开发一个 android 应用程序并第一次使用 Kotlin。该程序执行以下操作:

1) 登录

2) 将数据写入数据库(Firebase 实时数据库)

3) 从数据库中读取数据(RecycleView + Adapter with ViewHolder)

4) 用户:普通、管理员、特殊

“普通”用户可以使用 RecycleView + ViewHolder 输入数据并查看数据库对象; “管理员”可以通过单击按钮覆盖数据库中对象中的特定标识符(其他用户不可见); “特殊”用户可以使用 RecycleView + ViewHolder 查看具有特定标识符的对象。

问题是:“特殊”用户的特定 RecycleView 不起作用。活动只是崩溃。 RecycleView 的适配器工作:数据由“普通”用户提交到数据库,数据在 TextView + ViewHolder 中正确显示,即使在通过管理员用户更新后也是如此。

这是我的代码(### 表示为测试目的而硬编码的哈希):

class SchadenAdapter : RecyclerView.Adapter<SchadenViewHolder>() {
[...]
class SchadenViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(schaden: Schaden) {

    val userId: String = FirebaseAuth.getInstance().currentUser!!.uid

    itemView.textViewSchadenort.text = schaden.schadenort
    itemView.textViewSchadenart.text = schaden.schadenart
    itemView.textViewSchadendatum.text = schaden.datum
    itemView.textViewSchadenstatus.text = schaden.status

    if (userId == "###") {
        itemView.buttonTextViewAllocate.setOnClickListener() {
            (R.layout.item_schaden)
            // show message box after button click
            AlertDialog.Builder(itemView.context)
                .setMessage("Schaden zugeteilt.")
                .create()
                .show()
            // get uuid: update "allocate" + "status"
            val rootRef = FirebaseDatabase.getInstance().reference
            val uuidRef = schaden.uuid
            rootRef.child("schäden")
                .child(uuidRef)
                .child("allocated")
                .setValue("###")
            rootRef.child("schäden")
                .child(uuidRef)
                .child("status")
                .setValue("###")
        }
    } else {
        itemView.buttonTextViewAllocate.setVisibility(View.GONE)
    }
}
}

起初我尝试为“特殊”用户做同样的事情:我在 layout.xml 中创建了一个按钮,并在适配器中使用了相同的结构——唯一的区别是他们只能通过单击来更改“状态”一个按钮。但每次我尝试这样做时,应用程序都会崩溃。

为了完整起见,下面是使用 Adapter 的 Activity 的代码:

class SchadenListeActivity : AppCompatActivity() {

private lateinit var databaseReference: DatabaseReference
private lateinit var schadenAdapter: SchadenAdapter

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

    databaseReference = FirebaseDatabase.getInstance().reference
    schadenAdapter = SchadenAdapter()

    recyclerViewSchadenliste.layoutManager = LinearLayoutManager(this)
    recyclerViewSchadenliste.adapter = schadenAdapter
    val itemDecor = DividerItemDecoration(this, VERTICAL)
    recyclerViewSchadenliste.addItemDecoration(itemDecor)

    databaseReference.child("schäden")
        .addValueEventListener(object : ValueEventListener {
        override fun onCancelled(databaseError: DatabaseError) {
            Toast.makeText(this@SchadenListeActivity,
                "Database error: $databaseError.message", Toast.LENGTH_SHORT).show()
        }

        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val schadenListe = dataSnapshot.children.mapNotNull { it.getValue<Schaden>(Schaden::class.java) }
            schadenAdapter.setSchaden(schadenListe)
        }
    })
}
}

非常感谢您的帮助。

【问题讨论】:

  • 如果应用程序崩溃,会有一个堆栈跟踪。请在 logcat 上查找,并将其添加到您的问题中。
  • Martin Zeiler 我的问题与您发布的问题不重复。我不想将多种视图类型放入一个回收器视图中。我只是想创建不同的事件视图持有者,以便我可以使用一个回收器视图,但为不同的用户角色获得不同的输出。
  • Alex Mamo 谢谢你的建议。我发现了问题:我从一个事件视图持有者复制并粘贴了代码,但忘记更改按钮的名称。所以这是一个错字。现在可以了。谢谢。

标签: android kotlin firebase-realtime-database android-recyclerview


【解决方案1】:

我不太确定应用程序崩溃,我可以观察到看到您的代码是您正在尝试使用 itemView.context 显示警报对话框,这是不可能的。您只能使用activity context 显示对话框。尝试使用活动上下文显示对话框并检查它是否仍然崩溃。

请提供您当前应用崩溃的堆栈跟踪。

【讨论】:

  • 谢谢,但警报有效。问题是一个错字。我从第一部分复制并粘贴了代码,却忘记将其调整为另一个按钮的 ID。一定是睡眠太少了。但感谢您的意见。
猜你喜欢
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多