【问题标题】:FirebaseRecyclerAdapter shows one item instead of an arrayFirebaseRecyclerAdapter 显示一个项目而不是一个数组
【发布时间】:2021-02-17 20:39:43
【问题描述】:

我的回收站视图只显示我数据中的最后一项。我想展示所有内容。

数据结构:

{
  "messages" : {
    "-MLLiVKuT5anOHM_6x8T" : {
      "senderId" : "rebecca@example.com",
      "senderName" : "Rebecca",
      "text" : "It happens to be where Josh lives",
      "type" : "OUTGOING"
    },
    "-MLLiYGcGhPv3E8xdbyh" : {
      "senderId" : "rebecca@example.com",
      "senderName" : "Rebecca",
      "text" : "But that's not why I'm here",
      "type" : "OUTGOING"
    },
    "-MLLm8JruMp_P99e2-SY" : {
      "senderId" : "rebecca@example.com",
      "senderName" : "Rebecca",
      "text" : "She's a crazy ex-girlfriend",
      "type" : "OUTGOING"
    }
  }
}

片段:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    // ...
    val messageManager = LinearLayoutManager(context).apply {
        stackFromEnd = true
    }
    message_list.layoutManager = messageManager

    messageAdapter = MessageAdapter.create(chatViewModel.messagesQuery, viewLifecycleOwner, CURRENT_USER.id)
    message_list.adapter = messageAdapter
}

查看模型:

class ChatViewModel : ViewModel() {

    private val database by lazy { Firebase.database.reference }

    private val messagesRef by lazy { database.child(MESSAGES_CHILD) }

    val messagesQuery: Query by lazy { messagesRef.limitToLast(MESSAGE_LIMIT) }

    val messageTextInput: ObservableField<String> = ObservableField("")

    fun sendMessage() {
        val messageText = messageTextInput.get()
        val message = Message(
            senderId = CURRENT_USER.id,
            senderName = CURRENT_USER.name,
            text = messageText,
            type = Message.Type.OUTGOING
        )
        messagesRef.push().setValue(message)
        messageTextInput.set("")
    }
}

适配器:

class MessageAdapter(options: FirebaseRecyclerOptions<Message>) :
    FirebaseRecyclerAdapter<Message, MessageViewHolder>(options) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder =
        when (Message.Type.values()[viewType]) {
            Message.Type.INCOMING -> MessageViewHolder.Incoming.create(parent)
            Message.Type.OUTGOING -> MessageViewHolder.Outgoing.create(parent)
        }

    override fun onBindViewHolder(viewHolder: MessageViewHolder, position: Int, message: Message) {
        Log.d("MessageAdapter#onBindViewHolder", "message: $message")
        viewHolder.bind(message)
    }

    override fun getItemViewType(position: Int): Int = getItem(position).type!!.ordinal

    companion object {

        fun create(query: Query, lifecycleOwner: LifecycleOwner, currentUserId: String): MessageAdapter {
            val parser = SnapshotParser<Message> {
                val message = it.getValue(Message::class.java)
                Log.d("MessageAdapter#create", "message: $message")
                message?.id = it.key
                message?.type = if (message?.senderId == currentUserId) {
                    Message.Type.OUTGOING
                } else {
                    Message.Type.INCOMING
                }
                message ?: Message()
            }
            val options =
                FirebaseRecyclerOptions.Builder<Message>()
                    .setQuery(query, parser)
                    .setLifecycleOwner(lifecycleOwner)
                    .build()
            return MessageAdapter(options)
        }
    }
}

片段布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="viewModel" type="ogbe.eva.bloomer.viewmodels.chat.ChatViewModel"/>
    </data>
    <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".views.chat.ChatFragment">

        <com.google.android.material.appbar.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <com.google.android.material.appbar.MaterialToolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    style="@style/Widget.MaterialComponents.Toolbar.Primary"/>

        </com.google.android.material.appbar.AppBarLayout>

        <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/message_list"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintBottom_toTopOf="@id/divider"
                    android:layout_margin="@dimen/spacing_md"
                    tools:listitem="@layout/item_message_outgoing"/>

            <View
                    android:id="@+id/divider"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintBottom_toTopOf="@id/message_text_input"
                    android:background="@color/divider_color"/>

            <EditText
                    android:id="@+id/message_text_input"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toLeftOf="@id/send_message_button"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:hint="@string/message_text_hint"
                    android:importantForAutofill="no"
                    android:text="@={viewModel.messageTextInput}"
                    style="@style/MessageTextInput"/>

            <com.google.android.material.button.MaterialButton
                    android:id="@+id/send_message_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:layout_marginEnd="@dimen/spacing_md"
                    android:enabled="@{viewModel.isSendButtonEnabled}"
                    android:onClick="@{(view) -> viewModel.sendMessage()}"
                    android:text="@string/send_message_button"/>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

项目布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="message" type="ogbe.eva.bloomer.domain.Message"/>
    </data>
    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end"
                android:background="@drawable/outgoing_message_bg"
                android:text="@{message.text}"
                android:textIsSelectable="true"
                style="@style/MessageItemText"
                tools:text="It happens to be where Josh lives"/>

    </FrameLayout>
</layout>

适配器似乎正在处理onBindViewHolder 和解析器中的所有消息,但只显示一条消息。

我看到this question 很相似,但不是重复的。接受的答案说在数据库中使用一组值。我试图从接受的答案中导入确切的数组,它说它是无效的 JSON。如果我应该使用一个数组,我如何在数据库中插入一个?如果没有,我还能如何显示我的整个数据结构?

【问题讨论】:

  • 查看列表计数
  • @RanaUmer 它在onBindViewHolder 中说项目数是 3
  • 你也可以发布xml吗
  • @RanaUmer 好的,我已经添加了
  • 我的意思是recyclerview项目文件xml

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


【解决方案1】:

请尝试按照以下方式更新您的项目布局。

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="message" type="ogbe.eva.bloomer.domain.Message"/>
    </data>
    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end"
                android:background="@drawable/outgoing_message_bg"
                android:text="@{message.text}"
                android:textIsSelectable="true"
                style="@style/MessageItemText"
                tools:text="It happens to be where Josh lives"/>

    </FrameLayout>
</layout>

到:

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="message" type="ogbe.eva.bloomer.domain.Message"/>
    </data>
    <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end"
                android:background="@drawable/outgoing_message_bg"
                android:text="@{message.text}"
                android:textIsSelectable="true"
                style="@style/MessageItemText"
                tools:text="It happens to be where Josh lives"/>

    </FrameLayout>
</layout>

编码愉快!

【讨论】:

  • 天哪,我是个白痴。我一直在看错误的地方。谢谢!
猜你喜欢
  • 2020-07-25
  • 2015-01-12
  • 2020-09-29
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多