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)
}
}
}
}







![[附源码]Python计算机毕业设计Django贷款申请审核管理系统论文](https://img-blog.csdnimg.cn/d0bad222f0e746a083cd1792922d0fce.png)






![[附源码]Python计算机毕业设计Django大学生心理测评系统](https://img-blog.csdnimg.cn/3c06bc5b377a4ba7b05a8014ca4c97cc.png)




