Kotlin: Как использовать RecycleView + ViewAdapter, чтобы разные пользователи получали разные ViewHolders? - PullRequest
0 голосов
/ 12 января 2020

Я работаю над приложением android и впервые использую Kotlin. Программа выполняет следующие действия:

1) Вход в систему

2) Запись данных в базу данных (база данных Firebase Realtime)

3) Чтение данных из базы данных (RecycleView + адаптер с ViewHolder )

4) Пользователи: Обычный, Администратор, Специальный

«Обычные» пользователи могут вводить данные и просматривать объекты базы данных, используя RecycleView + ViewHolder; «Администратор» может перезаписать указанный идентификатор c в объектах в базе данных, нажав кнопку (которая невидима для других пользователей); «Специальные» пользователи могут только видеть те объекты с указанным в них идентификатором c, используя RecycleView + ViewHolder.

Проблема заключается в следующем: спецификация c RecycleView для «специальных» пользователей не не работает Активность просто падает. Adapter for RecycleView работает: данные отправляются в базу данных «обычными» пользователями, и данные корректно отображаются в TextView + ViewHolder даже после обновления через пользователя Admin.

Вот мой код (### представляет хэши которые жестко запрограммированы для тестирования):

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)
    }
}
}

Сначала я попытался сделать то же самое для «специальных» пользователей: я создал кнопку в макете. xml и просто использовал ту же структуру в Адаптер - единственная разница в том, что они могут изменять «статус» только нажатием кнопки. Но каждый раз, когда я пытался это сделать, приложение зависало.

Для полноты, вот код для 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)
        }
    })
}
}

Помощь очень важна.

1 Ответ

0 голосов
/ 12 января 2020

Я не совсем уверен, что приложение cra sh, я вижу, что ваш код показывает, что вы пытаетесь показать диалоговое окно с предупреждением, используя itemView.context, что невозможно. Вы можете показать диалог, используя только activity context. Попробуйте показать диалоговое окно, используя контекст активности, и проверьте, по-прежнему ли происходит сбой.

Пожалуйста, укажите трассировку стека вашего текущего приложения для sh.

...