【day21】创建对象列表(下)

昨天我们已经按照时间去新增我们的资料了,也得到列表啦,那麽我们今天就要来建立点击事件,因为如果只有显示,但是没办法到该页面的话,那就没办法聊到天啦,正所谓看得到吃不到,就没有意义啦!

但是..... 我们会有一个很大的问题就是,当我们今天从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来拿到的。

1.透过user_id拿到聊天对象的资料吧!!

虽然我觉得目前这样的写法不是很好,因为这样代表只要某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)
        }

2.判断是从哪个页面进去的

就跟刚刚提到的一样,我们从不同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

3.修改Read/Writev讯息的资料来源

基本上如果是从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,

            )
        }

好啦,这样就大功告成啦!

4.ActionBar跟BottomNavigation隐藏/秀出来

之前我们是透过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.finished


<<:  网路渗透测试工具-Legion

>>:  Day21 为什麽要研发AR-HUD,它和W-HUD不都是投影在挡风玻璃上吗?

Chapter5 - 当一个勤劳的园丁,来修剪我们美丽的树(I)Canvas绘图 Y型树枝(爱心型) + 控制分支的变化

提醒:本篇承接第三章 让我们说回那颗树 既然树是我们游戏场景的主体之一,首先当然是要来整修一下我们...

Day17 PHP的常用函数-2:数组

数组 array(): 生成一个数组 range(): 创建并返回一个包含指定范围的元素的数组 co...

Day 20 | Livewire 实作 Todo List(二): 完成/删除待办事项

接续昨天的内容。昨天做完了 新增待办事项 ,今天就来把 修改 跟 删除 的功能给做出来吧!! 功能三...

Day21 NodeJS-Express VI

今天的内容是Express部份的最後一哩路:Restful API与应用程序结构化。前几天从前端到後...

Day5. 活用Hash,掌握资料处理的诀窍

Day5. Hash in Ruby 今天我们会介绍Hash,Hash中文为杂凑,不过汉汉老师还是习...