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.ConstraintLayoutandroid: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.SwipeToLoadLayoutandroid: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.ChatRefreshHeaderViewandroid:id="@+id/swipe_refresh_header"android:layout_width="match_parent"android:layout_height="wrap_content" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/swipe_target"android:layout_width="match_parent"android:layout_height="wrap_content"android:scrollbars="vertical" /></com.aspsine.swipetoloadlayout.SwipeToLoadLayout><androidx.appcompat.widget.AppCompatImageViewandroid: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"/><EditTextandroid: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.ChatRecordButtonandroid: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.AppCompatImageViewandroid: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.ConstraintLayoutandroid: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.AppCompatImageViewandroid: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.AppCompatTextViewandroid: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.ConstraintLayoutandroid: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"><includeandroid: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"/><includeandroid: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_mainprivate 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 = 102private var toUserId : String = ""private var toUserName : String = ""private var adapter : ChatAdapter = ChatAdapter(RedpacketClick(), OnItemLongClick())private var account = DataStoreUtils.get(DataStoreParams.User.DS_ACCOUNT, "") as Stringprivate var navController : NavController? = nullprivate var isOpenRedpacketDialog = falseprivate var mRedpacketBalance = 0fprivate var mRedpacketFromUser = ""//每页13条private val PAGE_SIZE = 13//当前页private var PAGE_NUM = 1//从那一条开始(为保证最新的先显示, 先查询最后的,并且不能用desc查询)private var startNum = 0//总共多少条private var CHAT_TOTAL = 0companion 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 = 0fvar scrollY : Float = 0fvar linearLayoutManager: LinearLayoutManager? = nullprivate fun initView(){linearLayoutManager = LinearLayoutManager(requireContext())linearLayoutManager?.orientation = LinearLayoutManager.VERTICALswipe_target.layoutManager = linearLayoutManagerswipe_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 + itvar 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 + itvar 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 = falseSoftInputUtils.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.positionvar chatBean = adapter.getItemObject(position)chatBean?.let {//设置为点击状态it.isClick = 1adapter.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 = falseTagUtils.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.VISIBLEchat_add.visibility = View.GONE} else {chat_send.visibility = View.GONEchat_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 = accountvar toAccount: String = toUserIdCHAT_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.nickNamevar 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.contentif(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.contentchatBean.content = CommonUtils.Chat.getRedpacket(content).toString()} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_TRANSFER){var content = chatBean.contentchatBean.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 = 21private var mListEmoji : MutableList<EmojiBean> = ArrayList()fun initEmoji(){emojiViewModel.getAllEmoji()emojiViewModel.emojiListLiveData.observe(viewLifecycleOwner) {mListEmoji = itval vpEmoji: ViewPager = chat_emoji_viewpageval indEmoji: EmojiIndicatorView = chat_emoji_ivval inflater = LayoutInflater.from(activity)val pageSize: Int = EVERY_PAGE_SIZEval 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) {//每个页面创建一个recycleviewval recyclerView = inflater.inflate(R.layout.wc_chat_emoji_item_vprecy, vpEmoji, false) as RecyclerViewrecyclerView.layoutManager = GridLayoutManager(activity, 7)var entranceAdapter: EmojiAdapterif (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 = entranceAdapterviewList.add(recyclerView)entranceAdapter.setOnItemClickListener { adapter, view, position ->TagUtils.d("点击表情:${position} , ${adapter.getItem(position)}")var emojiBean = adapter.getItem(position) as EmojiBeanvar 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 = adapterindEmoji.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.balanceTagUtils.d("点击领取红包元: ${balance}")if(balance > 0){mRedpacketBalance = balancemRedpacketFromUser = redPacketBean.accountvar account = DataStoreUtils.getAccount()userViewModel.updateBalanceRedpacketServer(redPacketBean.position, account, CommonUtils.User.OPERATOR_PLUS, balance)}}}}@Subscribe(threadMode = ThreadMode.MAIN)fun onMessageCallback(obj: Any) {//chatBean: ChatBeanif(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.GONEchat_audio.setImageResource(R.drawable.wc_chat_audio)}private fun showAudioButton(){chat_record_btn.visibility = View.VISIBLEchat_audio.setImageResource(R.drawable.wc_chat_keyboard)}private fun hideEmojiLayout() {TagUtils.d("隐藏emojiLayout")chat_emoji_layout.visibility = View.GONEchat_emoji.setImageResource(R.drawable.wc_chat_emoji)}private fun showEmojiLayout(){chat_content.requestFocus()chat_emoji_layout.visibility = View.VISIBLEchat_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 = softInputHeightchat_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 = falseoverride fun onResume() {super.onResume()chat_main_root.isFocusableInTouchMode = truechat_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 = 0private 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次,直接退出appbasePopupWindow?.baseDismiss()isReallyBack = trueSystem.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 = falseif(startNum >= PAGE_SIZE){startNum = CHAT_TOTAL - PAGE_SIZE * PAGE_NUMchatViewModel.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.attributesparams.alpha = 0.5fwindow.attributes = paramspopupWindow.setOnDismissListener {params.alpha = 1.0fwindow.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>? = nullvar 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.VISIBLEholder.otherLayout.visibility = View.GONEchatBean.avatarReally = CommonUtils.Base.getReallyImage(meAvatar)holder.meLayout.process(chatBean, onClickInterface)} else {//朋友holder.meLayout.visibility = View.GONEholder.otherLayout.visibility = View.VISIBLEchatBean.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 = chatListnotifyDataSetChanged()}//删除某个fun remove(position: Int){this.chatList?.removeAt(position)notifyDataSetChanged()}fun getItemObject(position : Int) : ChatBean? = chatList?.get(position)override fun getItemCount() = chatList?.size?:0class 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"><TextViewandroid: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.ChatOtherViewandroid: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.ChatMeViewandroid: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.GONEchat_item_other_content_layout.visibility = View.VISIBLEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_video.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_transfer.visibility = View.GONEchat_item_other_content.text = chatBean.content} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){//图片chat_item_other_img.visibility = View.VISIBLEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_video.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_transfer.visibility = View.GONEvar imagePath = chatBean.imgPathLocalif(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.GONEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.VISIBLEchat_item_other_voice_second.text = "${chatBean.second}'"chat_item_other_video.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_transfer.visibility = View.GONEchat_item_other_voice_layout.setOnClickListener {var voicePath = chatBean.voiceLocalAudioUtils.playChatVoice(ChatBean.USER_TYPE_OTHER, voicePath, chat_item_other_voice)}} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){//小视频chat_item_other_img.visibility = View.GONEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_video.visibility = View.VISIBLEchat_item_other_transfer.visibility = View.GONEvar 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.GONEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_mapview.visibility = View.VISIBLEchat_item_other_video.visibility = View.GONEchat_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.GONEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.VISIBLEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_video.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_transfer.visibility = View.GONEif(chatBean.isClick == 1){chat_item_other_redpacket.setBackgroundResource(R.drawable.wc_redpacket_left_click_normal)other_redpacket_icon.background.alpha = 100chat_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 = 255other_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.GONEchat_item_other_content_layout.visibility = View.GONEchat_item_other_redpacket.visibility = View.GONEchat_item_other_voice_layout.visibility = View.GONEchat_item_other_video.visibility = View.GONEchat_item_other_mapview.visibility = View.GONEchat_item_other_transfer.visibility = View.VISIBLEtransfer_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 = 255chat_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.GONEchat_item_me_content_layout.visibility = View.VISIBLEchat_item_me_redpacket.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.GONEchat_item_me_content.text = chatBean.contentchat_item_me_transfer.visibility = View.GONE} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){//图片chat_item_me_redpacket.visibility = View.GONEchat_item_me_img.visibility = View.VISIBLEchat_item_me_content_layout.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.GONEchat_item_me_transfer.visibility = View.GONEvar imagePath = chatBean.imgPathLocalif(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.GONEchat_item_me_content_layout.visibility = View.GONEchat_item_me_redpacket.visibility = View.GONEchat_item_me_voice_layout.visibility = View.VISIBLEchat_item_me_voice_second.text = "${chatBean.second}'"chat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.GONEchat_item_me_transfer.visibility = View.GONEchat_item_me_voice_layout.setOnClickListener {var voicePath = chatBean.voiceLocalAudioUtils.playChatVoice(ChatBean.USER_TYPE_ME, voicePath, chat_item_me_voice)}} else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){//小视频chat_item_me_img.visibility = View.GONEchat_item_me_content_layout.visibility = View.GONEchat_item_me_redpacket.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.VISIBLEchat_item_me_mapview.visibility = View.GONEchat_item_me_transfer.visibility = View.GONEvar 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.GONEchat_item_me_content_layout.visibility = View.GONEchat_item_me_redpacket.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.VISIBLEchat_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.VISIBLEchat_item_me_img.visibility = View.GONEchat_item_me_content_layout.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.GONEchat_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.GONEchat_item_me_img.visibility = View.GONEchat_item_me_content_layout.visibility = View.GONEchat_item_me_voice_layout.visibility = View.GONEchat_item_me_video.visibility = View.GONEchat_item_me_mapview.visibility = View.GONEchat_item_me_transfer.visibility = View.VISIBLEtransfer_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)}}}
}

Kotlin高仿微信-第8篇-单聊相关推荐

  1. Kotlin高仿微信-第11篇-单聊-语音

     Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册.登录.主页.单聊(文本.表情.语音.图片.小视频.视频通话.语音通话.红包.转账).群聊.个人信息.朋友圈.支付服务.扫一扫.搜 ...

  2. Kotlin高仿微信-第14篇-单聊-视频通话

    Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册.登录.主页.单聊(文本.表情.语音.图片.小视频.视频通话.语音通话.红包.转账).群聊.个人信息.朋友圈.支付服务.扫一扫.搜索 ...

  3. Flutter高仿微信-第36篇-单聊-语音通话

    Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 目前市 ...

  4. Flutter高仿微信-第31篇-单聊-表情

    Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 详情请 ...

  5. Flutter高仿微信-第32篇-单聊-语音

    Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 详情请 ...

  6. Flutter高仿微信-第47篇-群聊-语音

     Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 详情 ...

  7. Flutter高仿微信-第46篇-群聊-表情

    Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 详情请 ...

  8. Flutter高仿微信-第48篇-群聊-图片

     Flutter高仿微信系列共59篇,从Flutter客户端.Kotlin客户端.Web服务器.数据库表结构.Xmpp即时通讯服务器.视频通话服务器.腾讯云服务器全面讲解. 详情请查看 效果图: 详情 ...

  9. Kotlin高仿微信-第34篇-支付-向商家付款(二维码)

     Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册.登录.主页.单聊(文本.表情.语音.图片.小视频.视频通话.语音通话.红包.转账).群聊.个人信息.朋友圈.支付服务.扫一扫.搜 ...

最新文章

  1. k8s通过label来控制pod的位置
  2. oracle隐式转换函数,隐式数据类型转换案例一则
  3. [九度][何海涛] 栈的压入压出
  4. ASP.NET Core2读写InfluxDB时序数据库
  5. docker 镜像修改的配置文件自动还原_PVE部署LXC运行docker
  6. FreeSql 访问 Oracle 解决大小写问题
  7. 一览众山小的上一句是什么,怎么理解一览众山小的意思?
  8. objective-c(iOS5) 中weak和strong使用的区别
  9. Haxdoors of the Kaspersky Antivirus 6/7
  10. LabVIEW编程LabVIEW开发 Kepco ABC程控电源 例程与相关资料
  11. Android 中的 ClassLoader 摘抄笔记
  12. python用什么方式可以打印换行字符串_字符串是一个连续的字符序列,用________方式打印出可以换行的字符串。...
  13. PCB设计新手入门须知
  14. python压缩图片像素_python使用pil进行图像处理(等比例压缩、裁剪)实例代码
  15. Haclon例程注解之3d_matching_clamps
  16. 历时17小时的暖心春运 衢州火车站助84岁老人回家
  17. 18位身份证号码最后一位校验码的计算方法
  18. Pyhton操作Neo4j图数据库实践(南北朝隋唐历史北朝主要人物知识图谱)
  19. 【Android开发技巧】 关于Webview拍照或从相册上传图片处理总结
  20. java change()_Change.java

热门文章

  1. Android面试题整理(selfmade)——坚持每天回答一个
  2. mysql密码过期解决办法,mysql密码永不过期
  3. Dubbo遇到的异常-frozen class (cannot edit)
  4. 为什么html中没有折叠效果,css3折叠效果
  5. elif在python中啥意思_python中的elif是什么意思
  6. Android Studio系列(二)使用AS开发/调试整个android系统源代码(不定时更新)
  7. 架构面试精讲第三节 分布式技术RPC、MQ、Redis、Mysql、restful详解
  8. c语言编辑编译链接,C语言的“编译、链接”
  9. 单选框使用removeAttr清除选中状态后再使用attr无法赋予选中状态
  10. 《计算机视觉》集大网课学习笔记【5】