发送文件,图片,视频,处理失败

This commit is contained in:
itgaojian 2024-11-04 17:36:18 +08:00
parent 0d841e370d
commit db9ad383fa
35 changed files with 844 additions and 138 deletions

View File

@ -5,10 +5,12 @@ import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgMyAudioBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgMyBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgMyFileBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgMyImgBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgMyVideoBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgOtherAudioBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgOtherBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgOtherFileBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgOtherImgBinding
import com.tenlionsoft.aimz_k.databinding.ItemMsgOtherVideoBinding
import com.tenlionsoft.aimz_k.model.MsgBean
@ -16,67 +18,90 @@ import com.tenlionsoft.aimz_k.model.MsgTypeStateEnum
import com.tenlionsoft.aimz_k.viewmodel.ChatPageViewModel
import com.tenlionsoft.baselib.base.BaseBindingAdapter
class ChatMsgAdapter(datas: List<MsgBean>, viewModel: ChatPageViewModel) :
class ChatMsgAdapter(datas: List<MsgBean>, val viewModel: ChatPageViewModel) :
BaseBindingAdapter<MsgBean, ViewDataBinding>(datas) {
override fun getItemBinding(parent: ViewGroup, viewType: Int): ViewDataBinding {
when (viewType) {
MsgTypeStateEnum.MSG_TO_OTHER_TXT -> {
//发送文本
MsgTypeStateEnum.MSG_TO_OTHER_TXT ->
return ItemMsgOtherBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//发送文本
MsgTypeStateEnum.MSG_FROM_OTHER_TXT -> {
//收到文本信息
MsgTypeStateEnum.MSG_FROM_OTHER_TXT ->
return ItemMsgMyBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//收到文本信息
MsgTypeStateEnum.MSG_TO_OTHER_MOVIE -> {
return ItemMsgMyVideoBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//发送视频
MsgTypeStateEnum.MSG_FROM_OTHER_MOVIE -> {
//发送视频
MsgTypeStateEnum.MSG_TO_OTHER_MOVIE ->
return ItemMsgOtherVideoBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//收到视频
MsgTypeStateEnum.MSG_TO_OTHER_IMG -> {
return ItemMsgMyImgBinding.inflate(
//收到视频
MsgTypeStateEnum.MSG_FROM_OTHER_MOVIE ->
return ItemMsgMyVideoBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//发送图片
MsgTypeStateEnum.MSG_FROM_OTHER_IMG -> {
//发送图片
MsgTypeStateEnum.MSG_TO_OTHER_IMG ->
return ItemMsgOtherImgBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//收到图片
MsgTypeStateEnum.MSG_TO_OTHER_VOICE -> {
//收到图片
MsgTypeStateEnum.MSG_FROM_OTHER_IMG ->
return ItemMsgMyImgBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
//语音
MsgTypeStateEnum.MSG_TO_OTHER_VOICE ->
return ItemMsgMyAudioBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//语音
MsgTypeStateEnum.MSG_FROM_OTHER_VOICE -> {
//语音
MsgTypeStateEnum.MSG_FROM_OTHER_VOICE ->
return ItemMsgOtherAudioBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}//语音
//发送文件
MsgTypeStateEnum.MSG_TO_OTHER_FILE ->
return ItemMsgOtherFileBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
//收到文件
MsgTypeStateEnum.MSG_FROM_OTHER_FILE -> {
return ItemMsgMyFileBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
else -> {
throw IllegalArgumentException("Invalid view type")
}
@ -89,6 +114,9 @@ class ChatMsgAdapter(datas: List<MsgBean>, viewModel: ChatPageViewModel) :
override fun bindItem(holder: BaseViewHolder<ViewDataBinding>, position: Int) {
val itemType = getItemViewType(position)
holder.binding.root.setOnClickListener {
viewModel.onItemClickListener?.onItemClick(list[position])
}
when (itemType) {
//发送文本
MsgTypeStateEnum.MSG_TO_OTHER_TXT -> {
@ -104,28 +132,28 @@ class ChatMsgAdapter(datas: List<MsgBean>, viewModel: ChatPageViewModel) :
}
//发送视频
MsgTypeStateEnum.MSG_TO_OTHER_MOVIE -> {
(holder.binding as ItemMsgMyVideoBinding).pos = position
(holder.binding as ItemMsgMyVideoBinding).bean = list[position]
(holder.binding as ItemMsgMyVideoBinding).state = list[position].status
}
//收到视频
MsgTypeStateEnum.MSG_FROM_OTHER_MOVIE -> {
(holder.binding as ItemMsgOtherVideoBinding).pos = position
(holder.binding as ItemMsgOtherVideoBinding).bean = list[position]
(holder.binding as ItemMsgOtherVideoBinding).state = list[position].status
}
//收到视频
MsgTypeStateEnum.MSG_FROM_OTHER_MOVIE -> {
(holder.binding as ItemMsgMyVideoBinding).pos = position
(holder.binding as ItemMsgMyVideoBinding).bean = list[position]
(holder.binding as ItemMsgMyVideoBinding).state = list[position].status
}
//发送图片
MsgTypeStateEnum.MSG_TO_OTHER_IMG -> {
(holder.binding as ItemMsgMyImgBinding).pos = position
(holder.binding as ItemMsgMyImgBinding).bean = list[position]
(holder.binding as ItemMsgMyImgBinding).state = list[position].status
}
//收到图片
MsgTypeStateEnum.MSG_FROM_OTHER_IMG -> {
(holder.binding as ItemMsgOtherImgBinding).pos = position
(holder.binding as ItemMsgOtherImgBinding).bean = list[position]
(holder.binding as ItemMsgOtherImgBinding).state = list[position].status
}
//收到图片
MsgTypeStateEnum.MSG_FROM_OTHER_IMG -> {
(holder.binding as ItemMsgMyImgBinding).pos = position
(holder.binding as ItemMsgMyImgBinding).bean = list[position]
(holder.binding as ItemMsgMyImgBinding).state = list[position].status
}
//发送语音
MsgTypeStateEnum.MSG_TO_OTHER_VOICE -> {
(holder.binding as ItemMsgMyAudioBinding).pos = position
@ -138,6 +166,18 @@ class ChatMsgAdapter(datas: List<MsgBean>, viewModel: ChatPageViewModel) :
(holder.binding as ItemMsgOtherAudioBinding).bean = list[position]
(holder.binding as ItemMsgOtherAudioBinding).state = list[position].status
}
//发送文件
MsgTypeStateEnum.MSG_TO_OTHER_FILE -> {
(holder.binding as ItemMsgOtherFileBinding).pos = position
(holder.binding as ItemMsgOtherFileBinding).bean = list[position]
(holder.binding as ItemMsgOtherFileBinding).state = list[position].status
}
//收到文件
MsgTypeStateEnum.MSG_FROM_OTHER_FILE -> {
(holder.binding as ItemMsgMyFileBinding).pos = position
(holder.binding as ItemMsgMyFileBinding).bean = list[position]
(holder.binding as ItemMsgMyFileBinding).state = list[position].status
}
else -> {
throw IllegalArgumentException("Invalid view type")

View File

@ -0,0 +1,14 @@
package com.tenlionsoft.aimz_k.model
data class FileUploadStateBean(var code: Int, var data: FileDataBean)
//"fileId": "2b9dfe0b-ef6f-466c-84f6-8aedb7c97d8f",
//"fileName": "Screenshot_20230626_092232.jpg",
//"fileSize": 103874,
//"fileUrl": "api/file/download/2b9dfe0b-ef6f-466c-84f6-8aedb7c97d8f"
data class FileDataBean(
var fileId: String?,
var fileName: String?,
var fileSize: Long?,
var fileUrl: String
)

View File

@ -1,6 +1,7 @@
package com.tenlionsoft.aimz_k.net
import com.tenlionsoft.aimz_k.model.BaseSuccessBean
import com.tenlionsoft.aimz_k.model.FileUploadStateBean
import com.tenlionsoft.baselib.model.VersionBean
import okhttp3.MultipartBody
import okhttp3.RequestBody
@ -23,6 +24,7 @@ interface UserApi {
@Headers("Content-Type: application/json", "Accept: application/json", "projectName:usercenter")
@POST("api/jwt/login")
suspend fun doLogin(@Body user: RequestBody): BaseSuccessBean
/**
* 登陆Socket系统
* http://192.168.0.26:8888/system/api/anonymous/login
@ -43,7 +45,7 @@ interface UserApi {
/**
* 上传图片文件
* 上传图片
* image
*
* @param file
@ -52,8 +54,8 @@ interface UserApi {
*/
@Headers("token:need")
@Multipart
@POST("app/file/uploadimage")
suspend fun doUploadImage(@Part file: MultipartBody.Part): BaseSuccessBean
@POST("api/file/upload/image")
suspend fun doUploadImage(@Part file: MultipartBody.Part): FileUploadStateBean
/**
@ -66,6 +68,22 @@ interface UserApi {
*/
@Headers("token:need")
@Multipart
@POST("app/file/uploadvideo")
fun doUploadVideo(@Part file: MultipartBody.Part): BaseSuccessBean
@POST("api/file/upload/video")
suspend fun doUploadVideo(@Part file: MultipartBody.Part): FileUploadStateBean
/**
* 上传文件
*/
@Headers("token:need")
@Multipart
@POST("api/file/upload/file")
suspend fun doUploadFile(@Part file: MultipartBody.Part): FileUploadStateBean
/**
* 上传音频
*/
@Headers("token:need")
@Multipart
@POST("api/file/upload/audio")
suspend fun doUploadAudio(@Part file: MultipartBody.Part): FileUploadStateBean
}

View File

@ -16,11 +16,15 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.atwa.filepicker.core.FilePicker
import com.tenlionsoft.aimz_k.R
import com.tenlionsoft.aimz_k.databinding.ActivityChatBinding
import com.tenlionsoft.aimz_k.model.MsgBean
import com.tenlionsoft.aimz_k.model.PickerType
import com.tenlionsoft.aimz_k.viewmodel.ChatPageViewModel
import com.tenlionsoft.baselib.base.BaseActivity
import com.tenlionsoft.baselib.contacts.ProjectConfig
import com.tenlionsoft.baselib.utils.DensityUtils
import com.tenlionsoft.baselib.utils.SpUtils
import com.tenlionsoft.baselib.widget.AdapterItemClickListener
import com.tenlionsoft.baselib.widget.LoadingDialog
import com.tenlionsoft.baselib.widget.SoftKeyBoardListener
import com.tenlionsoft.baselib.widget.wheel.WheelView
@ -28,13 +32,14 @@ import com.tenlionsoft.baselib.widget.wheel.WheelView
/**
* 聊天页面
*/
class ChatActivity : BaseActivity() {
class ChatActivity : BaseActivity(), AdapterItemClickListener<MsgBean> {
private lateinit var mBinding: ActivityChatBinding
private lateinit var mLocalReceiver: LocalReceiver
var chatPageViewModel: ChatPageViewModel? = null
private val filePicker = FilePicker.getInstance(this)
private var mContentHeight: Int = 0
private var mLoading: LoadingDialog? = null;
private var bottomHeight = -1
override fun bindView() {
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_chat);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
@ -43,9 +48,7 @@ class ChatActivity : BaseActivity() {
val fromId = intent.getStringExtra("fromId") //传递过来的接收人
val name = intent.getStringExtra("name")
if (name.isNullOrEmpty()) {
mBinding.tvTitle.text = "临时客户"
}
mBinding.tvTitle.text = if (name.isNullOrEmpty()) "临时客户" else name
chatPageViewModel = ViewModelProvider(this, object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@ -54,7 +57,7 @@ class ChatActivity : BaseActivity() {
) as T
}
})[ChatPageViewModel::class.java]
chatPageViewModel!!.onItemClickListener = this
mBinding.ivBack.setOnClickListener { finish(); }
mBinding.viewModel = chatPageViewModel
mBinding.lifecycleOwner = this
@ -63,27 +66,57 @@ class ChatActivity : BaseActivity() {
mBinding.etMsg.append(it.emoji)
}
//显示/隐藏软键盘
// chatPageViewModel!!.showSoftKeyboard.observe(this) {
// if (it) {
// showSoftKeyBoard(mBinding.etMsg)
// chatPageViewModel!!.showChooseLayout.value = false
// chatPageViewModel!!.showEmojiLayout.value = false
// chatPageViewModel!!.showReplyLayout.value = false
// val layoutManager = mBinding.rlvChats.layoutManager as LinearLayoutManager
// val itemCount = layoutManager.itemCount
// mBinding.rlvChats.smoothScrollToPosition(itemCount - 1)
// } else {
// hideSoftKeyboard()
// }
// }
// mBinding.rlContent.setOnClickListener {
// Log.e("ChatActivity", "bindView: 点击")
// chatPageViewModel!!.showChooseLayout.value = false
// chatPageViewModel!!.showEmojiLayout.value = false
// chatPageViewModel!!.showReplyLayout.value = false
// hideSoftKeyboard()
// }
chatPageViewModel!!.showReplyLayout.observe(this) {
if (it) {
hideSoftKeyboard()//隐藏软键盘
setContentLayoutHeight()
} else {
val isShow =
chatPageViewModel!!.showEmojiLayout.value!! || chatPageViewModel!!.showChooseLayout.value!!
if (isShow) {
setContentDefaultHeight()
}
}
}
chatPageViewModel!!.showEmojiLayout.observe(this) {
if (it) {
hideSoftKeyboard()//隐藏软键盘
setContentLayoutHeight()
} else {
val isShow =
chatPageViewModel!!.showReplyLayout.value!! || chatPageViewModel!!.showChooseLayout.value!!
if (isShow) {
setContentDefaultHeight()
}
}
}
chatPageViewModel!!.showChooseLayout.observe(this) {
if (it) {
hideSoftKeyboard()//隐藏软键盘
setContentLayoutHeight()
} else {
val isShow =
chatPageViewModel!!.showEmojiLayout.value!! || chatPageViewModel!!.showReplyLayout.value!!
if (isShow) {
setContentDefaultHeight()
}
}
}
chatPageViewModel!!.showLoadDialog.observe(this) {
if (it) {
//显示loading
mLoading = LoadingDialog.Builder(this)
.setCancelOutside(false)
.setCancelable(false)
.setMessage("上传中...")
.create()
mLoading!!.show()
} else {
//隐藏loading
mLoading?.dismiss()
mLoading = null
}
}
mBinding.wvView.setTextSize(14F, isSp = true)
mBinding.wvView.setAutoFitTextSize(true)
mBinding.wvView.setOnItemSelectedListener(object : WheelView.OnItemSelectedListener {
@ -91,6 +124,7 @@ class ChatActivity : BaseActivity() {
mBinding.etMsg.setText(data.toString())
}
})
chatPageViewModel!!.chooseType.observe(this) {
when (it) {
PickerType.TYPE_PIC -> {
@ -121,7 +155,7 @@ class ChatActivity : BaseActivity() {
}
}
chatPageViewModel!!.scrollListToBottom.observe(this) {
Log.e("TAG", "bindView:滚动 ${it} ")
Log.e("TAG", "bindView:滚动 $it ")
if (it) {
val layoutManager = mBinding.rlvChats.layoutManager as LinearLayoutManager
val itemCount = layoutManager.itemCount
@ -136,14 +170,24 @@ class ChatActivity : BaseActivity() {
chatPageViewModel!!.scrollListToBottom.value = false
}
}
mBinding.llBottomLayout.visibility = View.VISIBLE
mBinding.rlBottom.visibility = View.GONE
mBinding.rlvChats.viewTreeObserver.addOnGlobalLayoutListener {
mContentHeight = mBinding.rlvChats.height
}
mBinding.llBottomLayout.viewTreeObserver.addOnGlobalLayoutListener {
if (mBinding.llBottomLayout.height == 0) {
bottomHeight = DensityUtils.dp2px(this@ChatActivity, 300F)
} else {
bottomHeight = mBinding.llBottomLayout.height
}
}
SoftKeyBoardListener().setChangeListener(this@ChatActivity,
{ h ->
mBinding.llBottomLayout.visibility = View.VISIBLE
Log.e("ChatActivity", "软键盘: 显示")
chatPageViewModel!!.showReplyLayout.value = false
chatPageViewModel!!.showEmojiLayout.value = false
chatPageViewModel!!.showChooseLayout.value = false
mBinding.rlBottom.visibility = View.VISIBLE
//重置layout高度
val layoutParams = mBinding.rlvChats.layoutParams
@ -158,16 +202,17 @@ class ChatActivity : BaseActivity() {
0
)
}, 100)
},
{ _ ->
val layoutParams = mBinding.rlvChats.layoutParams
layoutParams.height = mContentHeight
mBinding.rlvChats.layoutParams = layoutParams
mBinding.llBottomLayout.visibility = View.VISIBLE
mBinding.rlBottom.visibility = View.GONE
Log.e("ChatActivity", "软键盘: 隐藏")
val isShowOther =
chatPageViewModel!!.showReplyLayout.value!! || chatPageViewModel!!.showEmojiLayout.value!! || chatPageViewModel!!.showChooseLayout.value!!
if (!isShowOther) {
val layoutParams = mBinding.rlvChats.layoutParams
layoutParams.height = mContentHeight
mBinding.rlvChats.layoutParams = layoutParams
mBinding.rlBottom.visibility = View.GONE
}
})
registerLocalReceiver()
}
@ -185,6 +230,31 @@ class ChatActivity : BaseActivity() {
unregisterReceiver(mLocalReceiver)
}
private fun setContentLayoutHeight() {
mBinding.rlBottom.visibility = View.VISIBLE
//重置layout高度
val layoutParams = mBinding.rlvChats.layoutParams
layoutParams.height = mContentHeight - bottomHeight
Log.e("ChatActivity", "setContentLayoutHeight: $mContentHeight $bottomHeight")
mBinding.rlvChats.layoutParams = layoutParams
val layoutManager = mBinding.rlvChats.layoutManager as LinearLayoutManager
val itemCount = layoutManager.itemCount
//滚动到底部
mBinding.rlvChats.postDelayed({
layoutManager.scrollToPositionWithOffset(
itemCount - 1,
0
)
}, 100)
}
private fun setContentDefaultHeight() {
val layoutParams = mBinding.rlvChats.layoutParams
layoutParams.height = mContentHeight
mBinding.rlvChats.layoutParams = layoutParams
mBinding.rlBottom.visibility = View.GONE
}
override fun onDestroy() {
super.onDestroy()
unRegisterLocalReceiver()
@ -195,12 +265,17 @@ class ChatActivity : BaseActivity() {
when (intent?.action) {
ProjectConfig.A_S_MSG_RECEIVER -> {
val msg = intent.getStringExtra("msg")
Log.e("LocalReceiver", "onReceive: ${msg}")
Log.e("LocalReceiver", "onReceive: $msg")
chatPageViewModel!!.receiveMsg(msg)
}//接收到信息
}
}
}
//条目点击
override fun onItemClick(data: MsgBean) {
}
}

View File

@ -10,8 +10,8 @@ import com.tenlionsoft.baselib.base.BaseActivity
import com.tenlionsoft.baselib.widget.LoadingDialog
class LoginActivity : BaseActivity() {
private lateinit var mBinding: ActivityLoginBinding;
private var mLoading: LoadingDialog? = null;
private lateinit var mBinding: ActivityLoginBinding
private var mLoading: LoadingDialog? = null
private val loginPageViewModel: LoginPageViewModel by lazy {
ViewModelProvider(this)[LoginPageViewModel::class.java]
}
@ -40,13 +40,13 @@ class LoginActivity : BaseActivity() {
}
loginPageViewModel.isLoginSuccess.observe(this) {
if (it) {
// startActivity(Intent(this@LoginActivity, MainActivity::class.java))
startActivity(
Intent(
this@LoginActivity,
ChatActivity::class.java
).putExtra("fromId", "2")
)
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
// startActivity(
// Intent(
// this@LoginActivity,
// ChatActivity::class.java
// ).putExtra("fromId", "2").putExtra("name", "测试")
// )
finish()
}
}

View File

@ -90,7 +90,7 @@ class MainActivity : BaseActivity() {
return@setOnItemSelectedListener true;
}//我的
}
false;
false
}
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {

View File

@ -17,9 +17,10 @@ import com.tenlionsoft.aimz_k.page.activity.MainActivity
import com.tenlionsoft.aimz_k.services.SocketService
import com.tenlionsoft.aimz_k.viewmodel.MsgViewModel
import com.tenlionsoft.baselib.contacts.ProjectConfig
import com.tenlionsoft.baselib.widget.AdapterItemClickListener
import com.tenlionsoft.baselib.widget.LoadingDialog
class MsgFragment : Fragment(), MsgViewModel.OnItemClickListener,
class MsgFragment : Fragment(), AdapterItemClickListener<MsgCategoryBean>,
MainActivity.OnSocketConnectListener {
private lateinit var mMsgBinding: FragmentMsgBinding
private var mActivity: MainActivity? = null

View File

@ -59,6 +59,7 @@ class SocketService : Service(), WsManager.MsgCallBack {
}
@SuppressLint("UnspecifiedRegisterReceiverFlag")
private fun registerLocalReceiver() {
val intentFilter = IntentFilter()
mLocalReceiver = LocalReceiver()

View File

@ -2,6 +2,9 @@ package com.tenlionsoft.aimz_k.viewmodel
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.View
import androidx.lifecycle.MutableLiveData
@ -15,6 +18,7 @@ import com.tenlionsoft.aimz_k.adapter.ChatMsgAdapter
import com.tenlionsoft.aimz_k.model.BodyContent
import com.tenlionsoft.aimz_k.model.CoverSealedBean
import com.tenlionsoft.aimz_k.model.DbManager
import com.tenlionsoft.aimz_k.model.FileDataBean
import com.tenlionsoft.aimz_k.model.MsgBean
import com.tenlionsoft.aimz_k.model.MsgConvertBean
import com.tenlionsoft.aimz_k.model.PickerType
@ -23,9 +27,11 @@ import com.tenlionsoft.aimz_k.model.Sender
import com.tenlionsoft.aimz_k.net.UserApi
import com.tenlionsoft.baselib.base.BaseViewModel
import com.tenlionsoft.baselib.contacts.ProjectConfig
import com.tenlionsoft.baselib.net.ExParse
import com.tenlionsoft.baselib.net.RetrofitClient
import com.tenlionsoft.baselib.utils.SpUtils
import com.tenlionsoft.baselib.utils.TimeUtils
import com.tenlionsoft.baselib.widget.AdapterItemClickListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -34,7 +40,6 @@ import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
class ChatPageViewModel(
private val fromId: String,
private val toId: String,
@ -51,7 +56,34 @@ class ChatPageViewModel(
private val retrofitClient = RetrofitClient.getInstance(context)
private val netApi = retrofitClient.create(UserApi::class.java)
var adapter: ChatMsgAdapter = ChatMsgAdapter(_msgList.value ?: emptyList(), this)
var onItemClickListener: AdapterItemClickListener<MsgBean>? = null
private val mGson: Gson = Gson()
private var msgHandlerList: ArrayList<MsgConvertBean> = arrayListOf()
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
val mBean: MsgConvertBean = msg.obj as MsgConvertBean
val isExist = msgHandlerList.contains(mBean)
if (isExist) {
// 更新数据库 发送失败
viewModelScope.launch {
withContext(Dispatchers.IO) {
val mDao = DbManager.db.msgDao()
val cDao = DbManager.db.categoryDao()
mDao.updateStatus(mBean.messageId, ProjectConfig.MSG_SEND_FAIL)
cDao.updateStatus(mBean.sender.senderId!!, ProjectConfig.MSG_SEND_FAIL)
}
for (item in _msgList.value!!) {
if (item.messageId == mBean.messageId) {
item.status = ProjectConfig.MSG_SEND_FAIL
}
}
adapter.setData(_msgList.value!!)
}
}
}
}
init {
Log.e("ChatPageViewModel", "Init: ${showSendBtn.value}")
@ -78,20 +110,18 @@ class ChatPageViewModel(
}
fun onShowReplyLayout() {
showReplyLayout.value = !showReplyLayout.value!!
showEmojiLayout.value = false
showChooseLayout.value = false
showSoftKeyboard.value = !showReplyLayout.value!!
showReplyLayout.value = !showReplyLayout.value!!
}
/**
* 切换emoji layout
*/
fun onShowEmojiLayout() {
showEmojiLayout.value = !showEmojiLayout.value!!
showChooseLayout.value = false
showReplyLayout.value = false
showSoftKeyboard.value = !showEmojiLayout.value!!
showEmojiLayout.value = !showEmojiLayout.value!!
}
@ -99,10 +129,9 @@ class ChatPageViewModel(
* 切换选择layout
*/
fun onShowChooseLayout() {
showChooseLayout.value = !showChooseLayout.value!!
showEmojiLayout.value = false
showReplyLayout.value = false
showSoftKeyboard.value = !showChooseLayout.value!!
showChooseLayout.value = !showChooseLayout.value!!
}
/**
@ -134,11 +163,83 @@ class ChatPageViewModel(
return
}
viewModelScope.launch {
doUploadImgs(list)
showLoadDialog.value = true
doUploadImages(list)
}
}
private suspend fun doUploadImgs(list: List<ImageMeta?>) {
/**
* 上传视频
*/
fun uploadVideo(meta: VideoMeta) {
viewModelScope.launch {
showLoadDialog.value = true
doUploadVideo(meta)
}
}
/**
* 上传文件
*/
fun uploadFiles(meta: FileMeta) {
viewModelScope.launch {
showLoadDialog.value = true
doUploadFile(meta)
}
}
private suspend fun doUploadVideo(meta: VideoMeta) {
try {
val requestFile: RequestBody =
meta.file!!.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body: MultipartBody.Part =
MultipartBody.Part.createFormData(
"video",
meta.file!!.getName(),
requestFile
)
val bean = retrofitClient.makeApiCall {
netApi.doUploadVideo(body)
}
if (bean.code == 200) {
sendMedia(ProjectConfig.MSG_VIDEO, bean.data)
}
showLoadDialog.value = false
} catch (e: Exception) {
e.printStackTrace()
showLoadDialog.value = false
ExParse.parse(e)
}
}
private suspend fun doUploadFile(meta: FileMeta) {
try {
val requestFile: RequestBody =
meta.file!!.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body: MultipartBody.Part =
MultipartBody.Part.createFormData(
"file",
meta.file!!.getName(),
requestFile
)
val bean = retrofitClient.makeApiCall {
netApi.doUploadFile(body)
}
if (bean.code == 200) {
sendMedia(ProjectConfig.MSG_FILE, bean.data)
}
showLoadDialog.value = false
} catch (e: Exception) {
e.printStackTrace()
showLoadDialog.value = false
ExParse.parse(e)
}
}
private var count: Int = 1
private suspend fun doUploadImages(list: List<ImageMeta?>) {
try {
for (item in list) {
if (item != null) {
@ -146,7 +247,7 @@ class ChatPageViewModel(
item.file!!.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body: MultipartBody.Part =
MultipartBody.Part.createFormData(
"audio",
"image",
item.file!!.getName(),
requestFile
)
@ -154,35 +255,40 @@ class ChatPageViewModel(
val bean = retrofitClient.makeApiCall {
netApi.doUploadImage(body)
}
Log.e("ChatPageViewModel", "doUploadImgs: $bean")
if (bean.code == 200) {
//上传成功
//TODO 构建消息实体
//TODO 发送消息
//
} else {
//TODO 上传失败
sendMedia(ProjectConfig.MSG_IMG, bean.data)
}
++count
}
}
if (count == list.size) {
showLoadDialog.value = false
count = 1
}
} catch (e: Exception) {
e.printStackTrace()
showLoadDialog.value = false
count = 1
ExParse.parse(e)
}
}
/**
* 上传视频
*/
fun uploadVideo(meta: VideoMeta) {
//发送 图片/视频/音频/文件
private fun sendMedia(type: String, data: FileDataBean) {
val intent = Intent(ProjectConfig.A_S_MSG_SEND)
val b = buildSendMediaBean(type, data)
viewModelScope.launch {
val msgBean = insertMsgBeanToDb(b)
_msgList.value = _msgList.value?.plus(msgBean)
adapter.setData(_msgList.value!!)
}
intent.putExtra("msgBean", b)
context.sendBroadcast(intent)
scrollListToBottom.value = true
}
/**
* 上传文件
*/
fun uploadFiles(meta: FileMeta) {
}
//刷新
private fun refresh() {
@ -198,6 +304,7 @@ class ChatPageViewModel(
_msgList.value = _msgList.value?.plus(msgBean)
adapter.setData(_msgList.value!!)
}
/**
* 发送文本信息
*/
@ -210,6 +317,10 @@ class ChatPageViewModel(
_msgList.value = _msgList.value?.plus(msgBean)
adapter.setData(_msgList.value!!)
}
// 保存发送信息到消息队列
//添加到消息队列
sendHandlerToLooper(b)
intent.putExtra("msgBean", b)
v.context.sendBroadcast(intent)
txtMsg.value = ""
@ -228,11 +339,18 @@ class ChatPageViewModel(
}
}
private fun sendHandlerToLooper(b: MsgConvertBean) {
msgHandlerList.add(b)
val msg = Message()
msg.what = b.timestamp.toInt()
msg.obj = b
handler.sendMessageDelayed(msg, 5000)
}
//收到消息
fun receiveMsg(msg: String?) {
if (!msg.isNullOrEmpty()) {
val bean = ConvertBeanUtils.covertBean(msg)
when (bean) {
when (val bean = ConvertBeanUtils.covertBean(msg)) {
//消息状态
is CoverSealedBean.StateBean -> {
viewModelScope.launch {
@ -244,6 +362,9 @@ class ChatPageViewModel(
dao.updateStatus(bean.data.messageId, statusType)
cDao.updateStatus(bean.data.sender.senderId!!, statusType)
}
//删除队列里面的Bean
msgHandlerList.removeIf { it.messageId == bean.data.messageId }
handler.removeMessages(bean.data.timestamp.toInt())
refresh()
}
}
@ -275,7 +396,7 @@ class ChatPageViewModel(
context.sendBroadcast(intent)
}
//构建发送实体
//构建文字发送实体
private fun buildSendBean(type: String): MsgConvertBean {
val bodyBean = BodyContent(content = txtMsg.value, null, null)
val body = mGson.toJson(bodyBean)
@ -298,6 +419,31 @@ class ChatPageViewModel(
)
}
//构建 图片/视频/文件发送实体
private fun buildSendMediaBean(type: String, fileBean: FileDataBean): MsgConvertBean {
val bodyBean = BodyContent(content = mGson.toJson(fileBean), null, null)
val body = mGson.toJson(bodyBean)
return MsgConvertBean(
body = body,
customMessageType = "",
messageId = TimeUtils.getNowDateMillis().toString(),
messageType = type,
metadata = "",
timestamp = TimeUtils.getNowDateMillis(),
sender = Sender(
senderId = SpUtils.getId(),
senderType = ""
),
receiver = Receiver(
receiverId = fromId,
receiverType = "SINGLE_USER"
),
status = ProjectConfig.MSG_SEND_ING,
)
}
//构建状态信息
private fun buildStatusBean(messageId: String): MsgConvertBean {
val bodyBean = BodyContent(content = null, msg = "", statusType = "SUCCESS_RECEIVED")
@ -320,4 +466,7 @@ class ChatPageViewModel(
status = "",
)
}
}
}

View File

@ -37,7 +37,7 @@ class LoginPageViewModel : BaseViewModel() {
}
fun doLogin() {
isLoginSuccess.value = true
// isLoginSuccess.value= true
val isLegal = checkParams();
if (isLegal) {
viewModelScope.launch {

View File

@ -19,6 +19,7 @@ import com.tenlionsoft.aimz_k.model.Sender
import com.tenlionsoft.baselib.contacts.ProjectConfig
import com.tenlionsoft.baselib.utils.SpUtils
import com.tenlionsoft.baselib.utils.TimeUtils
import com.tenlionsoft.baselib.widget.AdapterItemClickListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -26,7 +27,7 @@ import kotlinx.coroutines.withContext
class MsgViewModel : ViewModel() {
private val _pwdList = MutableLiveData<List<MsgCategoryBean>>()
var adapter: CategoryAdapter = CategoryAdapter(_pwdList.value ?: emptyList(), this)
var onItemClickListener: OnItemClickListener? = null
var onItemClickListener: AdapterItemClickListener<MsgCategoryBean>? = null
val isLogining = MutableLiveData(false)
private val mGson = Gson()
private var mCurrentPage: Int = 1
@ -156,8 +157,4 @@ class MsgViewModel : ViewModel() {
fun refresh() {
getList(true)
}
interface OnItemClickListener {
fun onItemClick(msgCategoryBean: MsgCategoryBean)
}
}

View File

@ -1,5 +1,8 @@
package com.tenlionsoft.aimz_k.widget
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
@ -10,11 +13,18 @@ import androidx.recyclerview.widget.RecyclerView.Adapter
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.google.gson.Gson
import com.tenlionsoft.aimz_k.R
import com.tenlionsoft.aimz_k.model.BodyContent
import com.tenlionsoft.aimz_k.model.FileDataBean
import com.tenlionsoft.baselib.contacts.NetConfig
import com.tenlionsoft.baselib.contacts.ProjectConfig
import com.tenlionsoft.baselib.model.ImageSize
import com.tenlionsoft.baselib.utils.ImageUtils
import com.tenlionsoft.baselib.utils.TimeUtils
import com.tenlionsoft.baselib.widget.chat.BubbleImageView
object BindingUtils {
@ -61,7 +71,131 @@ object BindingUtils {
} else {
val gson = Gson()
val body = gson.fromJson(str, BodyContent::class.java)
tv.text = body.content
val contains = body.content!!.contains("fileName")
if (contains) {
tv.text = "文件"
} else {
tv.text = body.content
}
}
}
@BindingAdapter("jsonConvertMsgFileIcon")
@JvmStatic
fun jsonConvertFileIcon(iv: ImageView, str: String?) {
if (str.isNullOrEmpty()) {
iv.visibility = View.GONE
} else {
iv.visibility = View.VISIBLE
val gson = Gson()
val body = gson.fromJson(str, BodyContent::class.java)
val contains = body.content!!.contains("fileName")
if (contains) {
val fileDataBean = gson.fromJson(body.content, FileDataBean::class.java)
if (!fileDataBean.fileName.isNullOrEmpty()) {
iv.visibility = View.VISIBLE
val suffix = fileDataBean.fileName!!.substring(
fileDataBean.fileName!!.lastIndexOf("."),
fileDataBean.fileName!!.length
)
Log.e("BindingUtils", "jsonConvertFileIcon: $suffix")
var id = R.drawable.ic_audio
when (suffix) {
".zip", ".rar", ".7z", ".gz", ".xz" -> iv.setImageResource(R.drawable.ic_zip)
".png", ".jpg", ".jpeg", ".svg", ".gif" -> iv.setImageResource(R.drawable.ic_image)
".doc", ".docx", ".wps", ".wpt" -> iv.setImageResource(R.drawable.ic_word)
".xls", ".xlsx", ".et", ".ett" -> iv.setImageResource(R.drawable.ic_excel)
".pdf" -> iv.setImageResource(R.drawable.ic_pdf)
else -> iv.setImageResource(R.drawable.ic_file)
}
} else {
iv.visibility = View.GONE
}
} else {
iv.visibility = View.GONE
}
}
}
@BindingAdapter("jsonConvertMsgFileName")
@JvmStatic
fun jsonConvertFileName(tv: TextView, str: String?) {
if (str.isNullOrEmpty()) {
tv.text = ""
} else {
val gson = Gson()
val body = gson.fromJson(str, BodyContent::class.java)
val contains = body.content!!.contains("fileName")
if (contains) {
val fileBean = gson.fromJson(body.content, FileDataBean::class.java)
tv.text = fileBean.fileName
} else {
tv.text = body.content
}
}
}
@BindingAdapter("jsonConvertMsgAudioImg")
@JvmStatic
fun jsonConvertAudioCover(iv: ImageView, str: String?) {
if (str.isNullOrEmpty()) {
iv.setImageResource(com.tenlionsoft.baselib.R.drawable.ic_img_load_err)
} else {
val options: RequestOptions = RequestOptions()
.placeholder(com.tenlionsoft.baselib.R.drawable.ic_loading) // 正在加载中的图片
.error(com.tenlionsoft.baselib.R.drawable.ic_img_load_err) // 加载失败的图片
val gson = Gson()
val bodyContent = gson.fromJson<BodyContent>(str, BodyContent::class.java)
val fileBean = gson.fromJson(bodyContent.content, FileDataBean::class.java)
Glide.with(iv.context)
.load(NetConfig.MAIN_URL + fileBean.fileUrl) // 图片地址
.apply(options)
.into(object : CustomTarget<Drawable?>() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable?>?
) {
val imageSize: ImageSize? =
ImageUtils.getImageSize((resource as BitmapDrawable).bitmap)
if (imageSize != null) {
val imageLP = iv.layoutParams
imageLP?.width = imageSize.getWidth()
imageLP?.height = imageSize.getHeight()
iv.setLayoutParams(imageLP)
Glide.with(iv.context)
.load(resource)
.apply(options) // 参数
.into(iv)
}
}
override fun onLoadCleared(placeholder: Drawable?) {
}
})
}
}
@BindingAdapter("jsonConvertMsgImgBody")
@JvmStatic
fun jsonConvertImg(view: BubbleImageView, str: String?) {
if (str.isNullOrEmpty()) {
view.setImageResource(com.tenlionsoft.baselib.R.drawable.ic_load_error)
} else {
val gson = Gson()
val body = gson.fromJson(str, BodyContent::class.java)
val fileData = gson.fromJson(body.content, FileDataBean::class.java)
val requestOptions = RequestOptions()
.error(R.drawable.app_logo_small)
.placeholder(R.drawable.app_logo_small)
.skipMemoryCache(false)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerInside()
Glide.with(view.context)
.load(NetConfig.MAIN_URL + fileData.fileUrl)
.apply(requestOptions)
.into(view)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

View File

@ -73,7 +73,6 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/green"
tools:listitem="@layout/item_msg_my" />

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="pos"
type="Integer" />
<variable
name="bean"
type="com.tenlionsoft.aimz_k.model.MsgBean" />
<variable
name="state"
type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_margin="5dp"
android:orientation="horizontal"
android:padding="8dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_weight="1"
android:gravity="end">
<RelativeLayout
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_toLeftOf="@id/tv_content">
<ProgressBar
android:id="@+id/pb_sending"
isShowLoading="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading" />
<ImageView
android:id="@+id/iv_msg_state_fail"
isShowFail="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
android:src="@drawable/msg_state_fail_resend"
tools:visibility="visible" />
</RelativeLayout>
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:background="@drawable/ic_message_text_send"
android:orientation="horizontal">
<ImageView
jsonConvertMsgFileIcon="@{bean.body}"
android:layout_width="32dp"
android:layout_height="32dp"
android:scaleType="fitXY" />
<TextView
jsonConvertMsgFileName="@{bean.body}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="文件名称文件名称文件名称文件名称文件名称文件名称.jpg" />
</LinearLayout>
</LinearLayout>
<ImageView
android:id="@+id/iv_user_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:scaleType="fitXY"
android:src="@drawable/ic_user_default" />
</LinearLayout>
</layout>

View File

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="pos"
type="Integer" />
@ -11,6 +12,7 @@
<variable
name="bean"
type="com.tenlionsoft.aimz_k.model.MsgBean" />
<variable
name="state"
type="String" />
@ -41,19 +43,19 @@
<ProgressBar
android:id="@+id/pb_sending"
isShowLoading="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
isShowLoading="@{state}"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading" />
<ImageView
android:id="@+id/iv_msg_state_fail"
isShowFail="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
isShowFail="@{state}"
android:src="@drawable/msg_state_fail_resend"
tools:visibility="visible" />
</RelativeLayout>
@ -68,6 +70,7 @@
<com.tenlionsoft.baselib.widget.chat.BubbleImageView
android:id="@+id/iv_content"
jsonConvertMsgImgBody="@{bean.body}"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentStart="true"

View File

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="pos"
type="Integer" />
@ -11,6 +12,7 @@
<variable
name="bean"
type="com.tenlionsoft.aimz_k.model.MsgBean" />
<variable
name="state"
type="String" />>
@ -41,18 +43,18 @@
<ProgressBar
android:id="@+id/pb_sending"
isShowLoading="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
isShowLoading="@{state}"
android:layout_centerInParent="true"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading" />
<ImageView
android:id="@+id/iv_msg_state_fail"
isShowFail="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
isShowFail="@{state}"
android:layout_centerInParent="true"
android:src="@drawable/msg_state_fail_resend"
tools:visibility="visible" />
@ -68,8 +70,9 @@
<com.tenlionsoft.baselib.widget.chat.BubbleImageView
android:id="@+id/iv_content"
android:layout_width="100dp"
android:layout_height="100dp"
jsonConvertMsgAudioImg="@{bean.body}"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignParentStart="true"
android:layout_marginStart="0dp"
android:adjustViewBounds="true"

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="pos"
type="Integer" />
<variable
name="bean"
type="com.tenlionsoft.aimz_k.model.MsgBean" />
<variable
name="state"
type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="left"
android:padding="8dp">
<ImageView
android:id="@+id/iv_user_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="fitXY"
android:src="@drawable/ic_user_default" />
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/ic_message_text_receive"
android:orientation="horizontal">
<TextView
jsonConvertMsgFileName="@{bean.body}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="文件名称文件名称文件名称文件名称文件名称文件名称.jpg" />
<ImageView
jsonConvertMsgFileIcon="@{bean.body}"
android:layout_width="32dp"
android:layout_height="32dp"
android:scaleType="fitXY" />
</LinearLayout>
<RelativeLayout
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp">
<ProgressBar
android:id="@+id/pb_sending"
isShowLoading="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading" />
<ImageView
android:id="@+id/iv_msg_state_fail"
isShowFail="@{state}"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
android:src="@drawable/msg_state_fail_resend"
tools:visibility="visible" />
</RelativeLayout>
</LinearLayout>
</layout>

View File

@ -47,6 +47,7 @@
android:layout_marginStart="0dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
jsonConvertMsgImgBody="@{bean.body}"
android:transitionName="sharedView"
app:angle="6dp"
app:arrowHeight="8dp"

View File

@ -45,6 +45,7 @@
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentStart="true"
jsonConvertMsgAudioImg="@{bean.body}"
android:layout_marginStart="0dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"

View File

@ -19,8 +19,9 @@ object ProjectConfig {
//消息类型
const val MSG_TEXT = "MSG_TEXT"
const val MSG_FILE = "MSG_FILE"
const val MSG_IMG = "MSG_IMG"
const val MSG_IMG = "MSG_IMAGE"
const val MSG_VIDEO = "MSG_VIDEO"
const val MSG_AUDIO = "MSG_AUDIO"
const val MSG_STATUS = "STATUS" //状态消息
const val MSG_SEND_ING: String = "PENDING"//11 //发送中
const val MSG_SEND_FAIL: String = "ERROR"//12 //发送失败

View File

@ -0,0 +1,21 @@
package com.tenlionsoft.baselib.model
class ImageSize {
private var width = 0
private var height = 0
fun getWidth(): Int {
return width
}
fun setWidth(width: Int) {
this.width = width
}
fun getHeight(): Int {
return height
}
fun setHeight(height: Int) {
this.height = height
}
}

View File

@ -1,5 +1,6 @@
package com.tenlionsoft.baselib.net
import android.util.Log
import com.tenlionsoft.baselib.contacts.NetConfig
import com.tenlionsoft.baselib.utils.SpUtils
import okhttp3.HttpUrl
@ -19,7 +20,10 @@ class BaseUrlInterceptor : Interceptor {
val oldHttpUrl = request.url;
val headers = request.headers("project");
//公共Token header
if (headers.indexOf("token") != -1) {
val tokens = request.headers("token")
Log.e("BaseUrlInterceptor", "intercept: $tokens")
if (tokens.isNotEmpty()) {
Log.e("BaseUrlInterceptor", "intercept: 添加公共Header")
builder.removeHeader("token")
builder.addHeader("X-WG-TOKEN", SpUtils.getToken())
builder.addHeader("X-WG-TYPE", "APP")
@ -43,7 +47,7 @@ class BaseUrlInterceptor : Interceptor {
.build();
return chain.proceed(builder.url(newFullUrl).build());
} else {
return chain.proceed(request);
return chain.proceed(builder.url(oldHttpUrl).build());
}
}
}

View File

@ -0,0 +1,62 @@
package com.tenlionsoft.baselib.utils
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.tenlionsoft.baselib.model.ImageSize
import java.io.ByteArrayOutputStream
import java.io.IOException
object ImageUtils {
fun getImageSize(bitmap: Bitmap?): ImageSize? {
val imageSize: ImageSize = ImageSize()
if (null == bitmap || bitmap.isRecycled) {
return null
}
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val byteTmp = baos.toByteArray()
try {
baos.close()
} catch (e: IOException) {
e.printStackTrace()
}
val bitmapOptions = BitmapFactory.Options()
bitmapOptions.inJustDecodeBounds = true
BitmapFactory.decodeByteArray(byteTmp, 0, byteTmp.size, bitmapOptions)
val outWidth = bitmapOptions.outWidth
val outHeight = bitmapOptions.outHeight
val maxWidth = 400
val maxHeight = 400
val minWidth = 150
val minHeight = 150
if (outWidth / maxWidth > outHeight / maxHeight) { //
if (outWidth >= maxWidth) { //
imageSize.setWidth(maxWidth)
imageSize.setHeight(outHeight * maxWidth / outWidth)
} else {
imageSize.setWidth(outWidth)
imageSize.setHeight(outHeight)
}
if (outHeight < minHeight) {
imageSize.setHeight(minHeight)
val width = outWidth * minHeight / outHeight
imageSize.setWidth(Math.min(width, maxWidth))
}
} else {
if (outHeight >= maxHeight) {
imageSize.setHeight(maxHeight)
imageSize.setWidth(outWidth * maxHeight / outHeight)
} else {
imageSize.setHeight(outHeight)
imageSize.setWidth(outWidth)
}
if (outWidth < minWidth) {
imageSize.setWidth(minWidth)
val height = outHeight * minWidth / outWidth
imageSize.setHeight(Math.min(height, maxHeight))
}
}
return imageSize
}
}

View File

@ -0,0 +1,5 @@
package com.tenlionsoft.baselib.widget
interface AdapterItemClickListener<D> {
fun onItemClick(data: D)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB