Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
Kotlin高仿微信-项目实践58篇,点击查看详情
效果图:
实现代码:
<?xml version="1.0" encoding="utf-8"?> <layout> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/chat_main_root" android:background="@drawable/wc_base_bg"> <include layout="@layout/wc_base_top_title"/> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="0dp" android:focusable="true" android:focusableInTouchMode="true" app:layout_constraintTop_toBottomOf="@+id/base_top_root_layout" app:layout_constraintBottom_toTopOf="@+id/chat_bottom_layout"> <com.aspsine.swipetoloadlayout.SwipeToLoadLayout android:id="@+id/swipeToLoadLayout" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@+id/chat_audio" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="12dp" android:layout_width="match_parent" android:layout_height="0dp"> <com.wn.wechatclientdemo.view.ChatRefreshHeaderView android:id="@+id/swipe_refresh_header" android:layout_width="match_parent" android:layout_height="wrap_content" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/swipe_target" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical" /> </com.aspsine.swipetoloadlayout.SwipeToLoadLayout> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/chat_audio" android:layout_width="38dp" android:layout_height="38dp" android:layout_marginBottom="10dp" android:layout_marginTop="100dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" android:src="@drawable/wc_chat_audio"/> <EditText android:id="@+id/chat_content" android:layout_width="0dp" android:layout_height="38dp" android:layout_marginHorizontal="10dp" android:paddingLeft="8dp" android:background="@drawable/chat_message_shap_bg" app:layout_constraintStart_toEndOf="@+id/chat_audio" app:layout_constraintEnd_toStartOf="@+id/chat_emoji" app:layout_constraintTop_toTopOf="@+id/chat_audio" app:layout_constraintBottom_toBottomOf="@+id/chat_audio"/> <com.wn.wechatclientdemo.view.ChatRecordButton android:id="@+id/chat_record_btn" android:layout_width="0dp" android:layout_height="38dp" android:visibility="gone" android:layout_marginHorizontal="10dp" android:background="@drawable/wc_chat_voice_selector" app:layout_constraintStart_toEndOf="@+id/chat_audio" app:layout_constraintEnd_toStartOf="@+id/chat_emoji" app:layout_constraintTop_toTopOf="@+id/chat_audio" app:layout_constraintBottom_toBottomOf="@+id/chat_audio" android:text="按住说话"/> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/chat_emoji" android:layout_width="38dp" android:layout_height="38dp" android:layout_marginEnd="10dp" app:layout_constraintEnd_toStartOf="@+id/chat_add_or_send" app:layout_constraintBottom_toBottomOf="@+id/chat_content" app:layout_constraintTop_toTopOf="@+id/chat_content" android:src="@drawable/wc_chat_emoji"/> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/chat_add_or_send" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="@+id/chat_content" app:layout_constraintTop_toBottomOf="@+id/chat_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/chat_add" android:layout_width="38dp" android:layout_height="38dp" android:layout_marginEnd="10dp" android:layout_marginBottom="10dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" android:visibility="visible" android:src="@drawable/wc_chat_add"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/chat_send" app:layout_constraintBottom_toBottomOf="@+id/chat_add_or_send" app:layout_constraintTop_toTopOf="@+id/chat_add_or_send" app:layout_constraintEnd_toEndOf="parent" android:layout_marginRight="10dp" android:layout_marginBottom="6dp" android:padding="6dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:visibility="gone" android:background="@drawable/wc_blue_light_shape" android:textColor="@color/blue" android:textStyle="bold" android:text="发送"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/chat_bottom_layout" android:layout_width="match_parent" android:layout_height="220dp" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> <include android:id="@+id/chat_add_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:visibility="gone" layout="@layout/wc_chat_add_layout"/> <include android:id="@+id/chat_emoji_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:visibility="visible" layout="@layout/wc_chat_emoji_layout"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/24 14:10 * Description : 聊天页面 */ class ChatFragment : BaseDataBindingFragment<WcChatMainBinding>() , OnRefreshListener{ override fun getLayoutRes()= R.layout.wc_chat_main private val chatViewModel: ChatViewModel by viewModels() private val emojiViewModel : EmojiViewModel by viewModels() private val userViewModel : UserViewModel by viewModels() private val vipViewModel : VipManagerViewModel by viewModels() private val REQUEST_PICTURE_CODE = 101 //申请权限 private val REQUEST_PERMISSION_CODE = 102 private var toUserId : String = "" private var toUserName : String = "" private var adapter : ChatAdapter = ChatAdapter(RedpacketClick(), OnItemLongClick()) private var account = DataStoreUtils.get(DataStoreParams.User.DS_ACCOUNT, "") as String private var navController : NavController? = null private var isOpenRedpacketDialog = false private var mRedpacketBalance = 0f private var mRedpacketFromUser = "" //每页13条 private val PAGE_SIZE = 13 //当前页 private var PAGE_NUM = 1 //从那一条开始(为保证最新的先显示, 先查询最后的,并且不能用desc查询) private var startNum = 0 //总共多少条 private var CHAT_TOTAL = 0 companion object { const val USER_ID = "CHAT_USER_ID" } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) TagUtils.d("ChatFragment 进入") //先判断是否已经注册 if(!EventBus.getDefault().isRegistered(this)){ EventBus.getDefault().register(this) } swipeToLoadLayout.setOnRefreshListener(this) //swipeToLoadLayout.setOnLoadMoreListener(this) 不适用加载更多 handlePermission() ChatNotificationUtils.setChatFragment(true) } override fun onPause() { super.onPause() AudioUtils.stopChatVoice() } private fun processInit(){ checkNetwork() initView() initListener() initEmoji() checkRenewall() } private fun processScrollToPosition(){ //保证在主线程中进行滑动操作 CoroutineScope(Dispatchers.Main).launch { delay(100) swipe_target.scrollToPosition(adapter.itemCount - 1) } } var scrollX : Float = 0f var scrollY : Float = 0f var linearLayoutManager: LinearLayoutManager? = null private fun initView(){ linearLayoutManager = LinearLayoutManager(requireContext()) linearLayoutManager?.orientation = LinearLayoutManager.VERTICAL swipe_target.layoutManager = linearLayoutManager swipe_target.adapter = adapter //处理点击发送消息框, 列表向上移动 chat_content.setOnClickListener { if(chat_bottom_layout.visibility == View.VISIBLE){ chat_bottom_layout.visibility = View.GONE } SoftInputUtils.showSoftInput(requireActivity(), chat_content) processScrollToPosition() } swipeToLoadLayout.setOnTouchListener { view, motionEvent -> SoftInputUtils.hideSoftInput(chat_content) hideBottomLayout() false } navController = findNavController() navController?.currentBackStackEntry?.savedStateHandle?.getLiveData<Float>(RedpacketFragment.REDPACKET_BALANCE)?.observe(viewLifecycleOwner){ TagUtils.d("红包返回金额:${it}") if(it > 0){ var content = CommonUtils.Chat.REDPACKET_MARK + it var chatBean = CommonUtils.Chat.getChatBean(account, toUserId, ChatBean.USER_TYPE_ME, content, ChatBean.CONTENT_TYPE_REDPACKET, "",0.0, 0.0) sendMessage(chatBean) } } navController?.currentBackStackEntry?.savedStateHandle?.getLiveData<Float>(CommonUtils.QRCommon.TRANSFER_BALANCE)?.observe(viewLifecycleOwner){ TagUtils.d("转账返回金额:${it}") if(it > 0){ var content = CommonUtils.Chat.TRANSFER_MARK + it var chatBean = CommonUtils.Chat.getChatBean(account, toUserId, ChatBean.USER_TYPE_ME, content, ChatBean.CONTENT_TYPE_TRANSFER, "",0.0, 0.0) sendMessage(chatBean) } } //录音完成回调 chat_record_btn.setOnFinishedRecordListener(object : ChatRecordButton.OnFinishedRecordListener{ override fun onFinishedRecord(audioPath: String, time: Int) { chat_content.isFocusable = false SoftInputUtils.hideSoftInput(chat_record_btn) AddFileListener.sendFile(ChatBean.CONTENT_TYPE_VOICE, audioPath, toUserId, time) } }) userViewModel.balanceRedpacketLiveData.observe(viewLifecycleOwner){ TagUtils.d("领取红包服务器返回:${it}") if(it.position >= 0){ //ToastUtils.makeText(requireActivity(), BaseUtils.getString(R.string.wc_receive_redpacket_success)) redPacketDialogUtils.dismissDialog() var position = it.position var chatBean = adapter.getItemObject(position) chatBean?.let { //设置为点击状态 it.isClick = 1 adapter.chatList?.set(position, it) adapter.notifyItemChanged(position) chatViewModel.updateChatClickByMessageIdLocal(it.isClick, it.messageId) } if(isOpenRedpacketDialog){ CoroutineScope(Dispatchers.Main).launch { var bundle = bundleOf(CommonUtils.QRCommon.BALANCE to mRedpacketBalance, CommonUtils.QRCommon.TO_USER to mRedpacketFromUser, CommonUtils.QRCommon.FROM_ACCOUNT to account) navController?.navigate(R.id.action_redpacket_success, bundle) } } isOpenRedpacketDialog = false TagUtils.d("点击的view值:${view}") } else { //ToastUtils.makeText(requireActivity(), BaseUtils.getString(R.string.wc_receive_redpacket_success)) } } } fun initListener(){ //发送文本消息 chat_send.setOnClickListener { var content = chat_content.text.toString() var chatBean = CommonUtils.Chat.getChatBean(account, toUserId, ChatBean.USER_TYPE_ME, content, ChatBean.CONTENT_TYPE_TEXT, "",0.0, 0.0) sendMessage(chatBean) chat_emoji.setImageResource(R.drawable.wc_chat_emoji) } //相册 chat_add_album.setOnClickListener { clickAddItem() sendPicture() } //拍摄 chat_add_small_video.setOnClickListener { clickAddItem() var bundle = bundleOf(CameraFragment.TYPE_ENTER to CameraFragment.TYPE_CHAT) navController?.navigate(R.id.action_svideo_camera, bundle) } //视频通话 chat_add_video_call.setOnClickListener { clickAddItem() showVideoPopupWindow() } //发送定位 chat_add_location.setOnClickListener { clickAddItem() var bundle = bundleOf(CommonUtils.Chat.TO_USER_ID to toUserId) Navigation.findNavController(it).navigate(R.id.action_baidu_map_poi, bundle) } //录音 chat_audio.setOnClickListener { if(chat_record_btn.isShown){ hideAudioButton() SoftInputUtils.showSoftInput(requireActivity(), chat_content) } else { showAudioButton() hideEmojiLayout() hideBottomLayout() SoftInputUtils.hideSoftInput(chat_content) processScrollToPosition() } } //表情 chat_emoji.setOnClickListener { showBottomLayout() showEmojiLayout() hideAddLayout() hideAudioButton() processScrollToPosition() } //加号 chat_add.setOnClickListener { showBottomLayout() hideEmojiLayout() showAddLayout() hideAudioButton() processScrollToPosition() } chat_content.addTextChangedListener(object : TextWatcher{ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if(s.length > 0){ chat_send.visibility = View.VISIBLE chat_add.visibility = View.GONE } else { chat_send.visibility = View.GONE chat_add.visibility = View.VISIBLE } } override fun afterTextChanged(s: Editable?) { } }) //红包 chat_add_radpacket.setOnClickListener { clickAddItem() navController?.navigate(R.id.action_redpacket) } //转账 chat_add_transfer.setOnClickListener { clickAddItem() var bundle = bundleOf(CommonUtils.QRCommon.TO_USER to toUserId) navController?.navigate(R.id.action_payment_transfer, bundle) } //文件 chat_add_file.setOnClickListener { clickAddItem() ToastUtils.showBaseTip() } //收藏 chat_add_collection.setOnClickListener { clickAddItem() ToastUtils.showBaseTip() } } private fun initData(){ //先进入页面,再刷新数据。 toUserId = arguments?.getString(USER_ID)?:"" super.builder().setTitleContent("") var fromAccount: String = account var toAccount: String = toUserId CHAT_TOTAL = chatViewModel.getChatCountByAccountAsync(fromAccount, toAccount) startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUM //先查询到我、朋友的头像 var fromUserBean = UserRepository.getUserByAccountSync(fromAccount) var toUserBean = UserRepository.getUserByAccountSync(toAccount) adapter.addMeAtavar(fromUserBean?.avatar) adapter.addOtherAtavar(toUserBean?.avatar) toUserName = toUserBean.nickName var friendIsAvailable = XmppConnectionManager.getInstance().getUserIsAvailable(toUserId) var titleContent = "" if(friendIsAvailable){ titleContent = toUserName + BaseUtils.getString(R.string.wc_chat_online) } else { titleContent = toUserName + BaseUtils.getString(R.string.wc_chat_offline) } super.builder().setTitleContent(titleContent) chatViewModel.getChatListByAccountPage(fromAccount, toAccount, startNum, PAGE_SIZE) chatViewModel.chatListLiveData.observe(viewLifecycleOwner){ if(PAGE_NUM == 1){ adapter.add(it) } else { adapter.refresh(it) } //滚动到底部 if(adapter.itemCount > 0){ linearLayoutManager?.scrollToPositionWithOffset(adapter.getItemCount() - 1, Integer.MIN_VALUE); } if(startNum > 0){ PAGE_NUM++ } swipeToLoadLayout.isRefreshing = false } } //发送图片 private fun sendPicture(){ //单选 // 打开相册 ImageSelector.builder() .useCamera(false) // 设置是否使用拍照 .setSingle(true) //设置是否单选 .canPreview(true) //是否点击放大图片查看,,默认为true .start(this,REQUEST_PICTURE_CODE) } //发送文本、红包、表情 private fun sendMessage(chatBean: ChatBean){ if(chatBean == null){ ToastUtils.makeText(requireActivity(), "发送信息不能为空") return } var content = chatBean.content if(TextUtils.isEmpty(content)){ ToastUtils.makeText(requireActivity(), "发送信息不能为空") } else { ChatManagerUtils.getInstance().sendMessage(toUserId, content) chat_content.setText("") CoroutineScope(Dispatchers.IO).launch { if(chatBean.contentType == ChatBean.CONTENT_TYPE_REDPACKET){ var content = chatBean.content chatBean.content = CommonUtils.Chat.getRedpacket(content).toString() } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){ var content = chatBean.content chatBean.content = CommonUtils.Chat.getTransfer(content).toString() } ChatRepository.insertChat(chatBean) } refreshBase(chatBean) } } /** * 刷新发送、接收聊天信息 * @param chatBean ChatBean */ private fun refreshBase(chatBean: ChatBean){ CoroutineScope(Dispatchers.Main).launch { //chatViewModel.insertChat(chatBean) TagUtils.d("ChatFragment refreshBase 刷新聊天信息 ") adapter.refresh(chatBean) if(chatBean.contentType == ChatBean.CONTENT_TYPE_LOCATION){ delay(200) } swipe_target.scrollToPosition(adapter.itemCount -1) } } val EVERY_PAGE_SIZE = 21 private var mListEmoji : MutableList<EmojiBean> = ArrayList() fun initEmoji(){ emojiViewModel.getAllEmoji() emojiViewModel.emojiListLiveData.observe(viewLifecycleOwner) { mListEmoji = it val vpEmoji: ViewPager = chat_emoji_viewpage val indEmoji: EmojiIndicatorView = chat_emoji_iv val inflater = LayoutInflater.from(activity) val pageSize: Int = EVERY_PAGE_SIZE val mEmojiBean = EmojiBean(0, 0) val deleteCount = Math.ceil(mListEmoji.size * 1.0 / EVERY_PAGE_SIZE) .toInt() //要显示的删除键的数量 //TagUtils.d("" + deleteCount) for (i in 1 until deleteCount + 1) { if (i == deleteCount) { mListEmoji.add(mListEmoji.size, mEmojiBean) } else { mListEmoji.add(i * EVERY_PAGE_SIZE - 1, mEmojiBean) } //TagUtils.d("添加次数$i") } val pageCount = Math.ceil(mListEmoji.size * 1.0 / pageSize).toInt() //一共的页数 //TagUtils.d("总共的页数:$pageCount") val viewList: MutableList<View> = ArrayList() for (index in 0 until pageCount) { //每个页面创建一个recycleview val recyclerView = inflater.inflate(R.layout.wc_chat_emoji_item_vprecy, vpEmoji, false) as RecyclerView recyclerView.layoutManager = GridLayoutManager(activity, 7) var entranceAdapter: EmojiAdapter if (index == pageCount - 1) { //最后一页的数据 val lastPageList: List<EmojiBean> = mListEmoji.subList( index * EVERY_PAGE_SIZE, mListEmoji.size ) entranceAdapter = EmojiAdapter(lastPageList) } else { entranceAdapter = EmojiAdapter( mListEmoji.subList( index * EVERY_PAGE_SIZE, (index + 1) * EVERY_PAGE_SIZE )) } entranceAdapter.setOnItemClickListener(object : BaseQuickAdapter.OnItemClickListener{ override fun onItemClick( adapter: BaseQuickAdapter<*, *>, view: View?, position: Int ) { if (mEmojiBean.id === 0) { //如果是删除键 //mEditText.dispatchKeyEvent( KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL ) ) } else { //mEditText.append((adapter.getData().get(position) as EmojiBean).getUnicodeInt() ) } } }) recyclerView.adapter = entranceAdapter viewList.add(recyclerView) entranceAdapter.setOnItemClickListener { adapter, view, position -> TagUtils.d("点击表情:${position} , ${adapter.getItem(position)}") var emojiBean = adapter.getItem(position) as EmojiBean var content = chat_content.text.toString() content += emojiBean.getEmojiStringByUnicode(emojiBean.unicode) chat_content.setText(content) //光标放在最后 chat_content?.setSelection(content.length) } } val adapter = EmojiVpAdapter(viewList) vpEmoji.adapter = adapter indEmoji.setIndicatorCount(vpEmoji.adapter!!.count) indEmoji.setCurrentIndicator(vpEmoji.currentItem) vpEmoji.addOnPageChangeListener(object : SimpleOnPageChangeListener() { override fun onPageSelected(position: Int) { indEmoji.setCurrentIndicator(position) } }) //TagUtils.d("Emoji初始化完毕") } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_PICTURE_CODE && data != null) { val images = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT) if(images != null && images.size > 0) { AddFileListener.sendFile(ChatBean.CONTENT_TYPE_IMG, images[0], toUserId,0) } } } override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if(requestCode == REQUEST_PERMISSION_CODE && grantResults != null && grantResults.size > 0){ if(grantResults[0] == PackageManager.PERMISSION_GRANTED){ //录音权限, 暂时不处理 processInit() } } } private fun handlePermission(){ if(checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) ||checkPermission(Manifest.permission.CAMERA) ||checkPermission(Manifest.permission.RECORD_AUDIO) ||checkPermission(Manifest.permission.ACCESS_FINE_LOCATION) ||checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION) ){ var permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION) requestPermissions(permissions, REQUEST_PERMISSION_CODE) } else { //录音权限, 暂时不处理 processInit() } } private fun checkPermission(permission: String) :Boolean { return ContextCompat.checkSelfPermission(requireActivity(), permission) != PackageManager.PERMISSION_GRANTED } private lateinit var redPacketDialogUtils : RedPacketDialogUtils //长按 inner class OnItemLongClick : WcOnItemLongClickInterface { override fun onItemLongClick(position: Int) { TagUtils.d("长按position:${position}"); var chatBean = adapter.getItemObject(position); TagUtils.d("长按chatBean:${chatBean?.content}"); showDeleteDialog(position) } } private var baseDialogUtils : BaseDialogUtils? = null //显示删除对话框 fun showDeleteDialog(position : Int){ var view = LayoutInflater.from(this.requireActivity()).inflate(R.layout.wc_chat_delete_tip, null) baseDialogUtils = BaseDialogUtils(this.requireActivity()) baseDialogUtils!!.builder() .showView(view) .setCancelable(false) .setOnLoadingClick(object : BaseDialogUtils.OnLoadingClick{ override fun onClickCancel() { } override fun onClickConfirm() { var chatBean = adapter.getItemObject(position) if(chatBean!=null){ chatViewModel.deleteChat(chatBean) } adapter.remove(position) } }) baseDialogUtils?.show() } //聊天页面点击红包 inner class RedpacketClick : WcOnItemClickInterface { override fun onItemClick(obj: Any) { if(!NetWorkUtils.isNetworkConnected()){ ToastUtils.makeText(requireActivity(), BaseUtils.getString(R.string.wc_base_network_tip)) return } TagUtils.d("点击红包打开按钮 ${obj}") var redPacketBean = obj as RedPacketBean //var redPacketBean = RedPacketBean("chaychan","https://img2.baidu.com/it/u=2059292981,3255805850&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200","大吉大利,今晚吃鸡") if(redPacketBean.isClick == 1){ var bundle = bundleOf(CommonUtils.QRCommon.BALANCE to redPacketBean.balance, CommonUtils.QRCommon.TO_USER to redPacketBean.account, CommonUtils.QRCommon.FROM_ACCOUNT to account) navController?.navigate(R.id.action_redpacket_success, bundle) } else { redPacketDialogUtils = RedPacketDialogUtils() redPacketDialogUtils.showRedPacketDialog(requireActivity(), redPacketBean, RedpacketDialogClick()) isOpenRedpacketDialog = true } } } //弹出红包对话框点击open按钮 inner class RedpacketDialogClick : RedPacketDialogClickInterface { override fun onOpenClick(redPacketBean: RedPacketBean) { if(!NetWorkUtils.isNetworkConnected()){ ToastUtils.makeText(requireActivity(), BaseUtils.getString(R.string.wc_base_network_tip)) redPacketDialogUtils.dismissDialog() return } GlobalScope.launch { delay(2000) //领取红包,调用接口 var balance = redPacketBean.balance TagUtils.d("点击领取红包元: ${balance}") if(balance > 0){ mRedpacketBalance = balance mRedpacketFromUser = redPacketBean.account var account = DataStoreUtils.getAccount() userViewModel.updateBalanceRedpacketServer(redPacketBean.position, account, CommonUtils.User.OPERATOR_PLUS, balance) } } } } @Subscribe(threadMode = ThreadMode.MAIN) fun onMessageCallback(obj: Any) { //chatBean: ChatBean if(obj == null){ return } TagUtils.d("接收对象:${obj}") //本地小视频回调 if(obj is SVideoBean){ TagUtils.d("接收对象type :${obj.type} , ${obj.filePath}") if(obj.type == CommonUtils.Moments.TYPE_PICTURE){ //图片 //processSendFile(obj.filePath, toUserId) AddFileListener.sendFile(ChatBean.CONTENT_TYPE_IMG, obj.filePath, toUserId, 0) } else if(obj.type == CommonUtils.Moments.TYPE_VIDEO){ //小视频 //processSendVideo(obj.filePath, toUserId) AddFileListener.sendFile(ChatBean.CONTENT_TYPE_VIDEO, obj.filePath, toUserId,0) } } //接收信息 if(obj is ChatBean){ if(obj.isReceive){ //接收信息, 当前聊天用户id页面才刷新 if(obj.fromAccount.equals(toUserId)){ refreshBase(obj) } } else { refreshBase(obj) } } } private fun hideAudioButton(){ chat_record_btn.visibility = View.GONE chat_audio.setImageResource(R.drawable.wc_chat_audio) } private fun showAudioButton(){ chat_record_btn.visibility = View.VISIBLE chat_audio.setImageResource(R.drawable.wc_chat_keyboard) } private fun hideEmojiLayout() { TagUtils.d("隐藏emojiLayout") chat_emoji_layout.visibility = View.GONE chat_emoji.setImageResource(R.drawable.wc_chat_emoji) } private fun showEmojiLayout(){ chat_content.requestFocus() chat_emoji_layout.visibility = View.VISIBLE chat_emoji.setImageResource(R.drawable.wc_chat_keyboard) } fun hideAddLayout(){ TagUtils.d("隐藏addLayout") chat_add_layout.visibility = View.GONE } fun showAddLayout(){ chat_add_layout.visibility = View.VISIBLE } fun hideBottomLayout() { //TagUtils.d("隐藏底部") chat_bottom_layout.visibility = View.GONE } fun showBottomLayout() { var softInputHeight: Int = BaseUtils.getDimension(R.dimen.wc_chat_emoji_height) SoftInputUtils.hideSoftInput(chat_content) chat_bottom_layout.getLayoutParams().height = softInputHeight chat_bottom_layout.visibility = View.VISIBLE } //点击底部按钮 fun clickAddItem(){ showAudioButton() hideEmojiLayout() hideBottomLayout() chat_content.clearFocus() SoftInputUtils.hideSoftInput(chat_content) processScrollToPosition() } override fun onDestroy() { super.onDestroy() EventBus.getDefault().unregister(this) ChatNotificationUtils.setChatFragment(false) SyncUtils.processInsertChatList() } private fun checkNetwork(){ if(!NetWorkUtils.isNetworkConnected()){ ToastUtils.makeText(R.string.wc_base_network_error) } } /** * 检查vip信息 */ private fun checkRenewall(){ //view加载完成 chat_main_root.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener{ override fun onGlobalLayout() { if(!TextUtils.isEmpty(account)){ vipViewModel.getVipLocal(account) } initData() chat_main_root.viewTreeObserver.removeOnGlobalLayoutListener(this) } }) vipViewModel.vipBeanLiveData.observe(viewLifecycleOwner){ if(it == null || !CommonUtils.Vip.isVip(it)){ showRenewalView() } } vipViewModel.vipBeanServerLiveData.observe(viewLifecycleOwner){ if(it == null){ ToastUtils.makeText(R.string.wc_vip_renewal_get_no_data) } else if(!CommonUtils.Vip.isVip(it)){ ToastUtils.makeText(R.string.wc_vip_renewal_get_no_vip) } else { basePopupWindow?.baseDismiss() //如果是vip,更新到本地数据库 vipViewModel.updateVipLocal(it) } } } private var basePopupWindow : BasePopupWindow? = null /** * 显示续费对话框 */ private fun showRenewalView(){ var view = LayoutInflater.from(WcApp.getContext()).inflate(R.layout.wc_vip_renewal_view, null) basePopupWindow = BasePopupWindow(requireActivity(), view) basePopupWindow?.let { it.baseSetOnDismissListener(object : BasePopupWindow.IOnDismissListener { override fun onDismiss() { TagUtils.d("dismiss 消失 ") } }) .setOnCancelListener( R.id.vip_renewal_cancel, object : BasePopupWindow.IOnCancelListener { override fun onCancelListener() { it.baseDismiss() System.exit(1) } }) .setOnConfirmListener( R.id.vip_renewal_get, object : BasePopupWindow.IOnConfirmListener { override fun onConfirmListener() { vipViewModel.getVipServer(account) } }) .baseSetFocusable(false) .baseShowAtLocation(chat_main_root) } } private var isReallyBack = false override fun onResume() { super.onResume() chat_main_root.isFocusableInTouchMode = true chat_main_root.requestFocus() chat_main_root.setOnKeyListener { view, i, keyEvent -> if (i == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { onBackPressed() } !isReallyBack } } private var exitTime: Long = 0 private fun onBackPressed() : Boolean { if(basePopupWindow != null && basePopupWindow?.isShowing!!){ if(System.currentTimeMillis() - exitTime > 1000){ ToastUtils.makeText(R.string.wc_two_back) exitTime = System.currentTimeMillis() isReallyBack = false } else { //连续点击2次,直接退出app basePopupWindow?.baseDismiss() isReallyBack = true System.exit(1) } } else { isReallyBack = true } return isReallyBack } //刷新是加载更多数据 override fun onRefresh() { TagUtils.d("onRefresh 执行 ${startNum} , ${CHAT_TOTAL}, ${PAGE_SIZE}, ${PAGE_NUM}") CoroutineScope(Dispatchers.Main).launch { delay(200) swipeToLoadLayout.isRefreshing = false if(startNum >= PAGE_SIZE){ startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUM chatViewModel.getChatListByAccountPage(account, toUserId, startNum, PAGE_SIZE) } else if(startNum > 0 && startNum < PAGE_SIZE){ //不够1页数据,查询全部,然后就不能下一页 chatViewModel.getChatListByAccountPage(account, toUserId, 0, startNum) startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUM } } } /** * 视频通话、语音通话 */ private fun showVideoPopupWindow(){ var popupView = layoutInflater.inflate(R.layout.wc_chat_video_pop_view , moment_root, false) var popupWindow = PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true) var popupRoot = popupView.findViewById<LinearLayout>(R.id.chat_video_pop_root) popupWindow.showAtLocation(popupRoot, Gravity.BOTTOM, 0, 0) var window = requireActivity().window //popupWindow在弹窗的时候背景半透明 val params = window.attributes params.alpha = 0.5f window.attributes = params popupWindow.setOnDismissListener { params.alpha = 1.0f window.attributes = params } //视频通话 popupView.findViewById<AppCompatTextView>(R.id.chat_pop_video_call).setOnClickListener { popupWindow.dismiss() CallSingleActivity.openActivity( requireActivity(),toUserId, true, toUserName, false, false) } //语音通话 popupView.findViewById<AppCompatTextView>(R.id.chat_pop_voice_call).setOnClickListener { popupWindow.dismiss() CallSingleActivity.openActivity( requireActivity(),toUserId, true, toUserName, true, false) } //取消 popupView.findViewById<AppCompatTextView>(R.id.chat_pop_cancel).setOnClickListener { popupWindow.dismiss() } } }
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/24 16:29 * Description : */ class ChatAdapter(var onClickInterface: WcOnItemClickInterface, var onLongClickInterface : WcOnItemLongClickInterface ) : RecyclerView.Adapter<ChatAdapter.ChatViewHolder>() { //我的头像 private var meAvatar = "" //我的其他人 private var otherAvatar = "" var chatList : MutableList<ChatBean>? = null var account = DataStoreUtils.getAccount() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder { var view = LayoutInflater.from(parent.context).inflate(R.layout.wc_chat_item, parent, false) return ChatViewHolder(view) } override fun onBindViewHolder(holder: ChatViewHolder, position: Int) { var chatBean = chatList?.get(position) chatBean?.let { //if(chatBean.userType == ChatBean.USER_TYPE_ME){ if(account.equals(chatBean.fromAccount)){ //我的 holder.meLayout.visibility = View.VISIBLE holder.otherLayout.visibility = View.GONE chatBean.avatarReally = CommonUtils.Base.getReallyImage(meAvatar) holder.meLayout.process(chatBean, onClickInterface) } else { //朋友 holder.meLayout.visibility = View.GONE holder.otherLayout.visibility = View.VISIBLE chatBean.avatarReally = CommonUtils.Base.getReallyImage(otherAvatar) holder.otherLayout.process(chatBean, onClickInterface, position) } holder.dateTextView.text = CommonUtils.Date.getCurrentDate(chatBean.addTime) } //长按 holder.rootLayout.setOnLongClickListener { onLongClickInterface.onItemLongClick(position) true } } fun addMeAtavar(meAvatar:String){ this.meAvatar = meAvatar } fun addOtherAtavar(otherAvatar:String){ this.otherAvatar = otherAvatar } //刷新单个 fun refresh(chatBean: ChatBean){ this.chatList?.add(chatBean) notifyItemInserted(itemCount) } //刷新多个 fun refresh(chatList : MutableList<ChatBean>){ //this.chatList?.addAll(chatList) this.chatList?.addAll(0, chatList) notifyItemInserted(itemCount) } fun add(chatList : MutableList<ChatBean>){ this.chatList = chatList notifyDataSetChanged() } //删除某个 fun remove(position: Int){ this.chatList?.removeAt(position) notifyDataSetChanged() } fun getItemObject(position : Int) : ChatBean? = chatList?.get(position) override fun getItemCount() = chatList?.size?:0 class ChatViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){ var dateTextView = itemView.findViewById<TextView>(R.id.chat_item_date) var otherLayout = itemView.findViewById<ChatOtherView>(R.id.chat_item_other_layout) var meLayout = itemView.findViewById<ChatMeView>(R.id.chat_item_me_layout) var rootLayout = itemView.findViewById<ConstraintLayout>(R.id.chat_item_root_layout) } }
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/chat_item_root_layout" android:layout_marginTop="16dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/chat_item_date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="聊天时间" android:textSize="14sp" android:textStyle="bold" android:textColor="@color/gray_hint" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <!--朋友的聊天信息--> <com.wn.wechatclientdemo.view.ChatOtherView android:id="@+id/chat_item_other_layout" app:layout_constraintTop_toBottomOf="@+id/chat_item_date" app:layout_constraintStart_toStartOf="parent" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <!--我的聊天信息--> <com.wn.wechatclientdemo.view.ChatMeView android:id="@+id/chat_item_me_layout" app:layout_constraintTop_toBottomOf="@+id/chat_item_date" app:layout_constraintEnd_toEndOf="parent" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </androidx.constraintlayout.widget.ConstraintLayout>
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/5/29 15:41 * Description : 聊天内容-其他人 */ class ChatOtherView : LinearLayout { constructor(context: Context) : this(context, null) constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0) constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr){ } init { LayoutInflater.from(context).inflate(R.layout.wc_chat_other_view, this) } fun process(chatBean: ChatBean, onClickInterface : WcOnItemClickInterface, position:Int){ GlideUtils.load(chat_item_other_avatar,chatBean.avatarReally, R.drawable.wc_avatar_default) if(chatBean.contentType == ChatBean.CONTENT_TYPE_TEXT){ //文字 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.VISIBLE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_video.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_transfer.visibility = View.GONE chat_item_other_content.text = chatBean.content } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){ //图片 chat_item_other_img.visibility = View.VISIBLE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_video.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_transfer.visibility = View.GONE var imagePath = chatBean.imgPathLocal if(File(imagePath).exists()){ } else { imagePath = CommonUtils.Base.getReallyImage(chatBean.imgPath) } GlideUtils.load(chat_item_other_img, imagePath) chat_item_other_img.setOnClickListener { var bundle = bundleOf(CommonUtils.Moments.TYPE_IMAGE_PATH to imagePath, CommonUtils.Moments.TYPE_NAME to CommonUtils.Moments.TYPE_PICTURE, CommonUtils.Chat.IS_HIDE_CONFIRM to true) Navigation.findNavController(it).navigate(R.id.action_svideo_play, bundle) } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VOICE){ //语音 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.VISIBLE chat_item_other_voice_second.text = "${chatBean.second}'" chat_item_other_video.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_transfer.visibility = View.GONE chat_item_other_voice_layout.setOnClickListener { var voicePath = chatBean.voiceLocal AudioUtils.playChatVoice(ChatBean.USER_TYPE_OTHER, voicePath, chat_item_other_voice) } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){ //小视频 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_video.visibility = View.VISIBLE chat_item_other_transfer.visibility = View.GONE var chatVideoUtils = ChatVideoUtils() chat_item_other_video.setSecond(chatBean.second) if(FileUtils.isFileExist(chatBean.videoLocal)){ //如果本地小视频存在,直接显示缩略图, 不播放 chat_item_other_video.setThumbnail(chatVideoUtils.createVideoThumbnail(chatBean.videoLocal)) //chat_item_other_video.initData(chatBean.videoLocal, false) } else { //如果小视频不存在,显示服务器缩略图 chat_item_other_video.setThumbnailServer(CommonUtils.Base.getReallyImage(chatBean.imgPath)) } chat_item_other_video.setOnClickListener { //如果小视频存在,查看详情 if(FileUtils.isFileExist(chatBean.videoLocal)){ var bundle = bundleOf(CommonUtils.Moments.TYPE_VIDEO_PATH to chatBean.videoLocal, CommonUtils.Moments.TYPE_NAME to CommonUtils.Moments.TYPE_VIDEO, CommonUtils.Chat.IS_HIDE_CONFIRM to true) Navigation.findNavController(it).navigate(R.id.action_svideo_play, bundle) } else { //如果小视频不存在,网络下载 chatVideoUtils.downloadVideo(chat_item_other_video, chatBean) } } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_LOCATION){ //定位 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_mapview.visibility = View.VISIBLE chat_item_other_video.visibility = View.GONE chat_item_other_transfer.visibility = View.GONE //点击地图 chat_item_other_mapview.setMapOnClick(object : OnMapClickInterface { override fun onMapClick() { var bundle = bundleOf(CommonUtils.Chat.LOCATION_LATITUDE to chatBean.latitude, CommonUtils.Chat.LOCATION_LONGITUDE to chatBean.longitude) Navigation.findNavController(chat_item_other_mapview).navigate(R.id.action_baidu_map_details, bundle) } }) chat_item_other_mapview.load(chatBean.latitude, chatBean.longitude) } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_REDPACKET){ //红包 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.VISIBLE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_video.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_transfer.visibility = View.GONE if(chatBean.isClick == 1){ chat_item_other_redpacket.setBackgroundResource(R.drawable.wc_redpacket_left_click_normal) other_redpacket_icon.background.alpha = 100 chat_item_other_redpacket.setOnClickListener { //已经领取的只能查看红包 var redPacketBean = RedPacketBean(position, chatBean.fromAccount, chatBean.content.toFloat(), "恭喜发财,大吉大利", chatBean.isClick) onClickInterface.onItemClick(redPacketBean) } } else { chat_item_other_redpacket.setBackgroundResource(R.drawable.wc_redpacket_left_normal) chat_item_other_redpacket.background.alpha = 255 other_redpacket_icon.background.alpha = 255 //还没领取红包才可以点击 chat_item_other_redpacket.setOnClickListener { TagUtils.d("领取红包:${chatBean.content} , position = ${position}") //var balance = CommonUtils.Chat.getRedpacket(chatBean.content) var redPacketBean = RedPacketBean(position, chatBean.fromAccount, chatBean.content.toFloat(), "恭喜发财,大吉大利", chatBean.isClick) onClickInterface.onItemClick(redPacketBean) } } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){ //转账 chat_item_other_img.visibility = View.GONE chat_item_other_content_layout.visibility = View.GONE chat_item_other_redpacket.visibility = View.GONE chat_item_other_voice_layout.visibility = View.GONE chat_item_other_video.visibility = View.GONE chat_item_other_mapview.visibility = View.GONE chat_item_other_transfer.visibility = View.VISIBLE transfer_other_balance.text = "${chatBean.content}" if(chatBean.isClick == 1){ transfer_other_content.text = "已收款" transfer_tip.setTextColor(BaseUtils.getColor(R.color.white88)) chat_item_other_transfer.setBackgroundResource(R.drawable.wc_redpacket_left_click_normal) other_redpacket_icon.background.alpha = 126 } else { chat_item_other_transfer.setBackgroundResource(R.drawable.wc_redpacket_left_normal) chat_item_other_transfer.background.alpha = 255 chat_item_other_transfer.background.alpha = 255 } //不管有没领取转账,点击都会进入详情 chat_item_other_transfer.setOnClickListener { var bundle = bundleOf(CommonUtils.QRCommon.TO_USER to chatBean.toAccount, CommonUtils.Chat.MESSAGE_ID to chatBean.messageId, CommonUtils.QRCommon.TRANSFER_BALANCE to chatBean.content ) Navigation.findNavController(it).navigate(R.id.action_transfer_details, bundle) } } } }
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/5/29 14:59 * Description : 聊天内容-我的 */ class ChatMeView : LinearLayout{ constructor(context: Context) : this(context, null) constructor(context: Context, attributeSet: AttributeSet?): this(context, attributeSet, 0) constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr :Int) : super(context, attributeSet, defStyleAttr){ init(context) } fun init(context: Context){ LayoutInflater.from(context).inflate(R.layout.wc_chat_me_view, this) } fun process(chatBean: ChatBean, onClickInterface : WcOnItemClickInterface){ //BaseUtils.showAvatar(chatBean.fromAccount, chat_item_me_avatar, chat_item_me_name) GlideUtils.load(chat_item_me_avatar,chatBean.avatarReally, R.drawable.wc_avatar_default) if(chatBean.contentType == ChatBean.CONTENT_TYPE_TEXT){ //文本 chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.VISIBLE chat_item_me_redpacket.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.GONE chat_item_me_content.text = chatBean.content chat_item_me_transfer.visibility = View.GONE } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){ //图片 chat_item_me_redpacket.visibility = View.GONE chat_item_me_img.visibility = View.VISIBLE chat_item_me_content_layout.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.GONE chat_item_me_transfer.visibility = View.GONE var imagePath = chatBean.imgPathLocal if(File(imagePath).exists()){ } else { imagePath = CommonUtils.Base.getReallyImage(chatBean.imgPath) } GlideUtils.load(chat_item_me_img, imagePath) chat_item_me_img.setOnClickListener { var bundle = bundleOf(CommonUtils.Moments.TYPE_IMAGE_PATH to imagePath, CommonUtils.Moments.TYPE_NAME to CommonUtils.Moments.TYPE_PICTURE, CommonUtils.Chat.IS_HIDE_CONFIRM to true) Navigation.findNavController(it).navigate(R.id.action_svideo_play, bundle) } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VOICE){ //语音 chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.GONE chat_item_me_redpacket.visibility = View.GONE chat_item_me_voice_layout.visibility = View.VISIBLE chat_item_me_voice_second.text = "${chatBean.second}'" chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.GONE chat_item_me_transfer.visibility = View.GONE chat_item_me_voice_layout.setOnClickListener { var voicePath = chatBean.voiceLocal AudioUtils.playChatVoice(ChatBean.USER_TYPE_ME, voicePath, chat_item_me_voice) } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){ //小视频 chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.GONE chat_item_me_redpacket.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.VISIBLE chat_item_me_mapview.visibility = View.GONE chat_item_me_transfer.visibility = View.GONE var chatVideoUtils = ChatVideoUtils() chat_item_me_video.setSecond(chatBean.second) if(FileUtils.isFileExist(chatBean.videoLocal)){ //如果本地小视频存在,直接显示缩略图, 不播放 chat_item_me_video.setThumbnail(chatVideoUtils.createVideoThumbnail(chatBean.videoLocal)) //chat_item_me_video.initData(chatBean.videoLocal, false) } else { //如果小视频不存在,显示服务器缩略图 chat_item_me_video.setThumbnailServer(CommonUtils.Base.getReallyImage(chatBean.imgPath)) } chat_item_me_video.setOnClickListener { //如果小视频存在,查看详情 if(FileUtils.isFileExist(chatBean.videoLocal)){ var bundle = bundleOf(CommonUtils.Moments.TYPE_VIDEO_PATH to chatBean.videoLocal, CommonUtils.Moments.TYPE_NAME to CommonUtils.Moments.TYPE_VIDEO, CommonUtils.Chat.IS_HIDE_CONFIRM to true) Navigation.findNavController(it).navigate(R.id.action_svideo_play, bundle) } else { //如果小视频不存在,网络下载 chatVideoUtils.downloadVideo(chat_item_me_video, chatBean) } } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_LOCATION){ //定位 chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.GONE chat_item_me_redpacket.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.VISIBLE chat_item_me_transfer.visibility = View.GONE //点击地图 chat_item_me_mapview.setMapOnClick(object : OnMapClickInterface { override fun onMapClick() { var bundle = bundleOf(CommonUtils.Chat.LOCATION_LATITUDE to chatBean.latitude, CommonUtils.Chat.LOCATION_LONGITUDE to chatBean.longitude) Navigation.findNavController(chat_item_me_mapview).navigate(R.id.action_baidu_map_details, bundle) } }) chat_item_me_mapview.load(chatBean.latitude, chatBean.longitude) } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_REDPACKET){ //红包 chat_item_me_redpacket.visibility = View.VISIBLE chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.GONE chat_item_me_transfer.visibility = View.GONE //点击红包 TagUtils.d("查看自己发送的红包") chat_item_me_redpacket.setOnClickListener { var bundle = bundleOf(CommonUtils.QRCommon.BALANCE to chatBean.content.toFloat(), CommonUtils.QRCommon.TO_USER to chatBean.toAccount, CommonUtils.QRCommon.FROM_ACCOUNT to chatBean.fromAccount) Navigation.findNavController(it)?.navigate(R.id.action_redpacket_success, bundle) } } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){ //转账 chat_item_me_redpacket.visibility = View.GONE chat_item_me_img.visibility = View.GONE chat_item_me_content_layout.visibility = View.GONE chat_item_me_voice_layout.visibility = View.GONE chat_item_me_video.visibility = View.GONE chat_item_me_mapview.visibility = View.GONE chat_item_me_transfer.visibility = View.VISIBLE transfer_me_balance.text = "${chatBean.content}" //点击红包 TagUtils.d("查看自己发送的转账") chat_item_me_transfer.setOnClickListener { var bundle = bundleOf(CommonUtils.QRCommon.TO_USER to chatBean.toAccount, CommonUtils.Chat.MESSAGE_ID to chatBean.messageId, CommonUtils.QRCommon.TRANSFER_BALANCE to chatBean.content ) Navigation.findNavController(it).navigate(R.id.action_transfer_details, bundle) } } } }