昨天我们已经按照时间去新增我们的资料了,也得到列表啦,那麽我们今天就要来建立点击事件,因为如果只有显示,但是没办法到该页面的话,那就没办法聊到天啦,正所谓看得到吃不到,就没有意义啦!
但是..... 我们会有一个很大的问题就是,当我们今天从A画面到ChatRoom的时候,我们的资料是从Invitation的资料丢进去的(来源是Firestore),但是如果今天使用者直接想要找我们之前聊过的人聊天呢? 那它不就没办法拿到之前的资料啦?
还记得我们昨天有新增一个LastMessage的dataClass吗? 太棒了,我们就直接从这边拿到资料吧!!
package com.example.petsmatchingapp.model
data class LastMessage(
val display_name: String = "",
val display_image: String = "",
val display_id: String = "",
val message: String = "",
val send_time: Long? = 0
)
★这里面的资料都是我们应该要显示的资讯,所以我们可以透过id来找Firestore相关的照片跟名字(因为我们在寄送讯息的时候会需要accepter的detail),而这些资讯之前是透过invitation的detail来拿到的。
虽然我觉得目前这样的写法不是很好,因为这样代表只要某user拿到其它人的userId,就可以看到它的资讯。之後有空再回来改!!
//一样想入livedata,好让我们之後可以观察
private val _selectedUserDetail = MutableLiveData<User>()
val selectedUserDetail: LiveData<User>
get() = _selectedUserDetail
fun findUserDetailByID(user_id: String){
Firebase.firestore.collection(Constant.USER).document(user_id).get()
.addOnSuccessListener {
_selectedUserDetail.postValue(it.toObject(User::class.java))
}
.addOnFailureListener {
}
}
接下来,我们就回到NotificationAdapter来设定onClick事件。
我们在onBindViewHolder新增
holder.itemView.setOnClickListener {
fragment.goChatRoom(model)
}
并且回到Notification来新增我们的导航跟把LastMessage传进去viewModel
fun goChatRoom(lastMessage: LastMessage){
chatViewModel.saveSelectedChatRoomUserDetail(lastMessage) findNavController().navigate(R.id.action_navigation_notifications_to_chatRoomFragment)
}
★ 这边也要记得在我们的Navigation连连看喔,不然找不到ID
来viewModel建立funtion,让我们储存UserDetail
private val _selectedChatRoomUserDetail = MutableLiveData<LastMessage>()
val selectedChatRoomUserDetail: LiveData<LastMessage>
get() = _selectedChatRoomUserDetail
fun saveSelectedChatRoomUserDetail(lastMessage: LastMessage){
_selectedChatRoomUserDetail.postValue(lastMessage)
}
然後来到我们的ChatRoomFragment来透过我们的ID,得到我们聊天者的Detail,别忘记要新增判断喔,不然如果我们的使用者直接从InvitationsDetail进入的话,那我们就拿不到selectedChatRoomUserDetail的值啦!!
if(chatViewModel.fromDetail.value == false){
accountViewModel.findUserDetailByID(chatViewModel.selectedChatRoomUserDetail.value!!.display_id)
}
就跟刚刚提到的一样,我们从不同Fragment进去的时候,我们的资料来源不一样,那我们可以怎麽办呢?!
於是乎,我们就用Flag来判断,我们首先在ChatViewModel来新增以下
private val _fromDetail = MutableLiveData<Boolean>()
val fromDetail: LiveData<Boolean>
get() = _fromDetail
fun setFromDetailOrNot(boolean: Boolean){
_fromDetail.postValue(boolean)
}
然後再这个两Fragment来修改它的值,既然它的取名是fromDetail的话,我们当然要在InvitationDetailFragment的时候更改它阿,并且改成true
chatViewModel.setFromDetailOrNot(true)
反之,在NotificationFragment我们把它设成false
基本上如果是从Detail的话,我们就不用修正,但是如果是从NotificationFragment的话,我们就需要作出修正! 我们直接丢刚刚透过点击事件得到的资料。
修改Read
if (chatViewModel.fromDetail.value == true) {
chatViewModel.messageValueListener(
this,
accountViewModel.userDetail.value!!.id,
matchingViewModel.selectedInvitation.value!!.user_id
)
matchingViewModel.selectedInvitation.value?.user_name?.let {
binding.tvChatRoomAcceptUserName.text = it
}
} else {
chatViewModel.messageValueListener(
this,
accountViewModel.userDetail.value!!.id,
chatViewModel.selectedChatRoomUserDetail.value!!.display_id
)
binding.tvChatRoomAcceptUserName.text = chatViewModel.selectedChatRoomUserDetail.value!!.display_name
}
修改write,我们只要修改来自Notification的资料,并把accept的资料都改成刚刚透过id,找到的Detail。
var message = Message()
if (chatViewModel.fromDetail.value == true){
message = Message(
user_name = accountViewModel.userDetail.value!!.name,
message = binding.edChatRoomInputMessage.text.toString().trim(),
send_user_id = accountViewModel.userDetail.value!!.id,
accept_user_id = matchingViewModel.selectedInvitation.value!!.user_id,
send_user_image = accountViewModel.userDetail.value!!.image,
send_user_name = accountViewModel.userDetail.value!!.name,
time = ServerValue.TIMESTAMP,
accept_user_image = matchingViewModel.selectedInvitation.value?.user_image,
accept_user_name = matchingViewModel.selectedInvitation.value?.user_name
)
}else{
message = Message(
user_name = accountViewModel.userDetail.value!!.name,
message = binding.edChatRoomInputMessage.text.toString().trim(),
send_user_id = accountViewModel.userDetail.value!!.id,
send_user_image = accountViewModel.userDetail.value!!.image,
send_user_name = accountViewModel.userDetail.value!!.name,
accept_user_name = accountViewModel.selectedUserDetail.value!!.name,
accept_user_image = accountViewModel.selectedUserDetail.value!!.image,
accept_user_id = accountViewModel.selectedUserDetail.value!!.id,
time = ServerValue.TIMESTAMP,
)
}
好啦,这样就大功告成啦!
之前我们是透过Invitation来进入chatRoom,所以我们在InvitationDetaiFragment就已经处理啦,那我们这时候如果直接从NotificationFragment,我们就需要再处理啦!
一样新增,并在onCreateView呼叫它
private fun dismissActivityActionBarAndBottomNavigationView() {
val activityInstance = this.activity as MatchingActivity
activityInstance.supportActionBar?.hide()
activityInstance.findViewById<BottomNavigationView>(R.id.nav_view).visibility = View.GONE
}
回到NotificationFragment,新增它并且在onResume呼叫它
private fun showActionBarAndBottomNavigation() {
if (requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility == View.GONE) {
requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility =
View.VISIBLE
}
val activityInstance = this.activity as MatchingActivity
activityInstance.supportActionBar?.show()
}
大功告成啦!
成品如下!!
>>: Day21 为什麽要研发AR-HUD,它和W-HUD不都是投影在挡风玻璃上吗?
提醒:本篇承接第三章 让我们说回那颗树 既然树是我们游戏场景的主体之一,首先当然是要来整修一下我们...
数组 array(): 生成一个数组 range(): 创建并返回一个包含指定范围的元素的数组 co...
接续昨天的内容。昨天做完了 新增待办事项 ,今天就来把 修改 跟 删除 的功能给做出来吧!! 功能三...
今天的内容是Express部份的最後一哩路:Restful API与应用程序结构化。前几天从前端到後...
Day5. Hash in Ruby 今天我们会介绍Hash,Hash中文为杂凑,不过汉汉老师还是习...