【发布时间】:2020-10-17 13:50:14
【问题描述】:
在我的数据库中,我有两个列表:聊天列表和用户列表。聊天列表中的每个项目都包含其各自用户的 ID。我需要将每个聊天与用户数据一起加载,以将其显示为 recyclerview 中的实时数据。如何在不破坏 MVVM 模式的情况下做到这一点?
数据库:
{
"chats" : {
"abc" : {
"userId" : "123",
"chatId" : "abc",
"lastMessage" : "message1"
},
"cde" : {
"userId" : "456",
"chatId" : "def",
"lastMessage" : "message2"
}
},
"users" : {
"abc" : {
"name" : "Name1",
"photo" : "photo.jpg",
"userId" : "abc",
"email" : "name1@gmail.com"
},
"def" : {
"name" : "Name2",
"photo" : "photo.jpg",
"userId" : "def",
"email" : "name2@gmail.com"
}
}
}
视图模型:
class ChatsViewModel:ViewModel() {
private val chatsRepository = ChatsRepository()
private var userRepository = UserRepository()
fun fetchChatsData(): LiveData<MutableList<Chat>> {
val mutableData = MutableLiveData<MutableList<Chat>>()
chatsRepository.getChatsData().observeForever { chatsList ->
mutableData.value = chatsList
}
return mutableData
}
fun fetchUserData(): LiveData<User> {
val mutableData = MutableLiveData<User>()
userRepository.getUserData("USER_ID_HERE").observeForever { user ->
mutableData.value = user
}
return mutableData
}
}
片段:
class ChatTabFragment2 : Fragment() {
private lateinit var fragmentView: View
private val viewModel by lazy { ViewModelProvider(this).get(ChatsViewModel::class.java) }
private lateinit var adapter:ChatsAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_chat_tab, container, false)
adapter = ChatsAdapter{
openChat(it.userId)
}
fragmentView.recycler_view.setHasFixedSize(true)
fragmentView.recycler_view.adapter = adapter
observeData()
return fragmentView
}
private fun observeData() {
viewModel.fetchChatsData().observe(viewLifecycleOwner, { chatsList ->
chatsList.let {
adapter.submitList(it)
}
})
}
聊天库:
class ChatsRepository {
private var chatsReference = FirebaseDatabase.getInstance().reference
.child(UserFirebase.id)
private lateinit var valueEventListener: ValueEventListener
fun getChatsData(): LiveData<MutableList<Chat>> {
val mutableData = MutableLiveData<MutableList<Chat>>()
valueEventListener = object :ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
val chatsList = mutableListOf<Chat>()
for (ds in snapshot.children) {
ds.getValue(Chat::class.java)?.let { chat ->
chatsList.add(chat)
}
}
mutableData.value = chatsList
}
override fun onCancelled(error: DatabaseError) {
}
}
chatsReference.addValueEventListener(valueEventListener)
return mutableData
}
}
用户存储库
class UserRepository {
fun getUserData(userId:String): LiveData<User> {
val mutableData = MutableLiveData<User>()
FirebaseDatabase.getInstance().reference.child("usersRef").child(userId)
.addListenerForSingleValueEvent(object :ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
mutableData.value = snapshot.getValue(User::class.java)
}
override fun onCancelled(error: DatabaseError) {}
})
return mutableData
}
}
【问题讨论】:
-
存储库中在做什么?您是在使用 Room/SQLite 来存储和检索这些数据,还是在谈论服务器中的数据库?请分享存储库代码。此外,如果您正在使用 Room,请同时共享 DAO 文件。如果我理解正确,您将希望在存储库中执行此合并操作,然后将所需的列表传递给 ViewModel,而不是在 ViewModel 中处理多个列表。
-
@SiddharthSharma 我正在使用 Firebase 实时数据库作为数据库,我想合并列表以显示一个列表,其中每个项目都是一个聊天 + 用户。
标签: android mvvm android-livedata android-architecture-components