【发布时间】: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