浏览代码

【聊天】宝贝家庭群头像当前为默认头像,需改为实际群成员头像

songchengcheng 3 月之前
父节点
当前提交
72e3e2f97b

+ 50 - 1
app/src/main/java/com/sikey/veryfit/k2/adapter/ChatMenuAdapter.kt

@@ -8,15 +8,18 @@ import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
+import com.android.volley.toolbox.ImageRequest
 import com.google.gson.Gson
 import com.sikey.veryfit.R
 import com.sikey.veryfit.app.DataManager.Companion.instance
+import com.sikey.veryfit.component.network.RequestManager
 import com.sikey.veryfit.component.network.http.model.ChatInfo
 import com.sikey.veryfit.component.receiver.CustomMIPushReceiver
 import com.sikey.veryfit.constant.UrlConstants
 import com.sikey.veryfit.k2.ui.chat.FamilyTalkActivity
 import com.sikey.veryfit.k2.ui.chat.PrivateTalkActivity
 import com.sikey.veryfit.ui.adapter.base.CustomBaseAdapter
+import com.sikey.veryfit.utils.GroupAvatarUtils
 import com.sikey.veryfit.utils.SharedPreferenceUtil
 
 /**
@@ -80,7 +83,7 @@ class ChatMenuAdapter(context: Context?, beanList: List<ChatInfo?>?) :
         val isGroup = info.type == UrlConstants.CHAT_TYPE_GROUP
         val avatarCache = instance.getAvatar(imageUrl)
         if (isGroup) {
-            holder.babyAvatarImageView!!.setImageResource(R.drawable.default_group_avater)
+            drawGroupAvatar(holder, info)
         } else {
             if (null != avatarCache) {
                 holder.babyAvatarImageView!!.setImageBitmap(avatarCache)
@@ -143,6 +146,52 @@ class ChatMenuAdapter(context: Context?, beanList: List<ChatInfo?>?) :
         return cv
     }
 
+    private fun drawGroupAvatar(holder: ViewHolder, info: ChatInfo) {
+        val targetSize = 125
+        val avatarCount = minOf(info.members.size, 4)
+        val avatars: MutableList<Bitmap?> = MutableList(avatarCount) { null }
+        var pendingLoads = avatarCount // 跟踪待加载的头像数量
+        var hasAsyncLoad = false // 标记是否有异步加载
+
+        // 定义绘制函数,确保只调用一次
+        fun drawFinalAvatar() {
+            if (pendingLoads == 0) {
+                val groupAvatar = GroupAvatarUtils.createGroupAvatar(avatars, targetSize)
+                holder.babyAvatarImageView?.setImageBitmap(groupAvatar)
+            }
+        }
+
+        // 遍历成员,加载头像
+        for (i in 0 until avatarCount) {
+            if (info.members[i].avatarUrl.isNullOrEmpty()) {
+                // 同步加载默认头像
+                avatars[i] = GroupAvatarUtils.loadVectorDrawableAsBitmap(
+                    mContext!!,
+                    R.drawable.default_guardian_avatar,
+                    targetSize
+                )
+                pendingLoads--
+            } else {
+                // 异步加载网络头像
+                hasAsyncLoad = true
+                val request = ImageRequest(
+                    info.members[i].avatarUrl,
+                    { response ->
+                        avatars[i] = response
+                        pendingLoads--
+                        drawFinalAvatar()
+                    }, 0, 0, Bitmap.Config.ARGB_8888, null
+                )
+                RequestManager.getInstance(mContext!!).addToRequestQueue<Bitmap>(request)
+            }
+        }
+
+        // 如果没有异步加载,直接绘制
+        if (!hasAsyncLoad) {
+            drawFinalAvatar()
+        }
+    }
+
     private class ViewHolder {
         var babyAvatarImageView: ImageView? = null
         var babyNickNameTv: TextView? = null

+ 51 - 3
app/src/main/java/com/sikey/veryfit/k2/ui/chat/ChatFamilyListActivity.kt

@@ -14,11 +14,10 @@ import com.sikey.veryfit.R
 import com.sikey.veryfit.app.DataManager.Companion.instance
 import com.sikey.veryfit.component.network.RequestManager
 import com.sikey.veryfit.component.network.http.model.ChatInfo
-import com.sikey.veryfit.data.DiskCacheControllerImpl
 import com.sikey.veryfit.k2.adapter.FamilyIconAdapter
 import com.sikey.veryfit.k2.entity.FamilyBean
 import com.sikey.veryfit.ui.avtivity.base.BaseNoActionBarActivity
-import com.sikey.veryfit.utils.BitmapTools
+import com.sikey.veryfit.utils.GroupAvatarUtils
 
 /**
  * A simple [Fragment] subclass.
@@ -101,7 +100,7 @@ class ChatFamilyListActivity : BaseNoActionBarActivity() {
     private fun loadAvatarFirst(mChildId: String?) {
         val (imageUrl, _, _,_, name) = instance.getChildInfoById(mChildId!!) ?: return
         mName!!.text = getString(R.string.whos_family_chat, name)
-        val img = DiskCacheControllerImpl.getInstance()[imageUrl]
+/*        val img = DiskCacheControllerImpl.getInstance()[imageUrl]
         img?.let {
             mIcon!!.setImageBitmap(BitmapTools.toCircleBitmap(it))
         }.let {
@@ -113,6 +112,55 @@ class ChatFamilyListActivity : BaseNoActionBarActivity() {
                     }
                 }, 0, 0, Bitmap.Config.ARGB_8888, null)
             RequestManager.getInstance(this).addToRequestQueue(request)
+        }*/
+        drawGroupAvatar()
+    }
+
+    private fun drawGroupAvatar() {
+        val targetSize = 125
+        val familyList = familyList ?: run {
+            mIcon?.setImageResource(R.drawable.default_guardian_avatar)
+            return
+        }
+        val avatarCount = minOf(familyList.size, 4)
+        val avatars: MutableList<Bitmap?> = MutableList(avatarCount) { null }
+        var pendingLoads = avatarCount
+        var hasAsyncLoad = false
+
+        fun drawFinalAvatar() {
+            if (pendingLoads == 0) {
+                //Logger.d(TAG, "All avatars processed, drawing group avatar with size=${avatars.size}")
+                val groupAvatar = GroupAvatarUtils.createGroupAvatar(avatars, targetSize)
+                mIcon?.setImageBitmap(groupAvatar)
+            }
+        }
+
+        for (i in 0 until avatarCount) {
+            val imageUrl = familyList.getOrNull(i)?.imageUrl
+            if (imageUrl.isNullOrEmpty()) {
+                avatars[i] = GroupAvatarUtils.loadVectorDrawableAsBitmap(
+                    this,
+                    R.drawable.default_guardian_avatar,
+                    targetSize
+                )
+                pendingLoads--
+            } else {
+                hasAsyncLoad = true
+                val request = ImageRequest(
+                    imageUrl,
+                    { response ->
+                        avatars[i] = response
+                        pendingLoads--
+                        //Logger.d(TAG, "Loaded avatar at index $i, pendingLoads=$pendingLoads")
+                        drawFinalAvatar()
+                    }, 0, 0, Bitmap.Config.ARGB_8888, null
+                )
+                RequestManager.getInstance(this).addToRequestQueue<Bitmap>(request)
+            }
+        }
+
+        if (!hasAsyncLoad) {
+            drawFinalAvatar()
         }
     }
 

+ 86 - 0
app/src/main/java/com/sikey/veryfit/utils/GroupAvatarUtils.kt

@@ -0,0 +1,86 @@
+package com.sikey.veryfit.utils
+
+import android.content.Context
+import android.graphics.*
+import androidx.core.content.ContextCompat
+import com.sikey.veryfit.component.log.Logger
+
+object GroupAvatarUtils {
+    // 成员头像URL列表转宫格头像
+    fun createGroupAvatar(memberAvatars: List<Bitmap?>, targetSize: Int): Bitmap {
+        // 创建目标Bitmap,尺寸为targetSize x targetSize
+        val resultBitmap = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888)
+        val canvas = Canvas(resultBitmap)
+
+        // 如果没有头像,返回空白Bitmap
+        if (memberAvatars.isEmpty()) {
+            return resultBitmap
+        }
+
+        // 取前四个非空头像
+        val validAvatars = memberAvatars.filterNotNull().take(4)
+        val avatarCount = validAvatars.size
+
+        when (avatarCount) {
+            1 -> {
+                // 单个头像,缩放到目标大小
+                val avatar = validAvatars[0]
+                val scaledAvatar = Bitmap.createScaledBitmap(avatar, targetSize, targetSize, true)
+                canvas.drawBitmap(scaledAvatar, 0f, 0f, null)
+            }
+            2 -> {
+                // 两个头像,左右排列
+                val avatarSize = targetSize / 2
+                validAvatars.forEachIndexed { index, avatar ->
+                    val scaledAvatar = Bitmap.createScaledBitmap(avatar, targetSize, targetSize, true)
+                    val left = if (index == 0) 0-avatarSize else avatarSize + 2
+                    canvas.drawBitmap(scaledAvatar, left.toFloat(), 0f, null)
+                }
+            }
+            3 -> {
+                // 三个头像,左右排列
+                val avatarSize = targetSize / 2
+                validAvatars.forEachIndexed { index, avatar ->
+                    if (index == 0) {
+                        val scaledAvatar = Bitmap.createScaledBitmap(avatar, targetSize, targetSize, true)
+                        val left = -avatarSize-2
+                        canvas.drawBitmap(scaledAvatar, left.toFloat(), 0f, null)
+                    } else if (index == 1) {
+                        val scaledAvatar = Bitmap.createScaledBitmap(avatar, avatarSize, avatarSize, true)
+                        canvas.drawBitmap(scaledAvatar, avatarSize.toFloat(), 0f, null)
+                    } else {
+                        val scaledAvatar = Bitmap.createScaledBitmap(avatar, avatarSize, avatarSize, true)
+                        val top = avatarSize + 2
+                        canvas.drawBitmap(scaledAvatar, avatarSize.toFloat(), top.toFloat(), null)
+                    }
+                }
+            }
+            4 -> {
+                // 四个头像,2x2宫格
+                val avatarSize = targetSize / 2 + 2
+                validAvatars.forEachIndexed { index, avatar ->
+                    val scaledAvatar = Bitmap.createScaledBitmap(avatar, avatarSize - 1, avatarSize - 1, true)
+                    val left = if (index % 2 == 0) 0 else avatarSize
+                    val top = if (index < 2) 0 else avatarSize
+                    canvas.drawBitmap(scaledAvatar, left.toFloat(), top.toFloat(), null)
+                }
+            }
+        }
+
+        return BitmapTools.toCircleBitmap(resultBitmap)
+    }
+
+    fun loadVectorDrawableAsBitmap(context: Context, drawableId: Int, targetSize: Int): Bitmap? {
+        try {
+            val drawable = ContextCompat.getDrawable(context, drawableId) ?: return null
+            val bitmap = Bitmap.createBitmap(targetSize, targetSize, Bitmap.Config.ARGB_8888)
+            val canvas = Canvas(bitmap)
+            drawable.setBounds(0, 0, targetSize, targetSize)
+            drawable.draw(canvas)
+            return bitmap
+        } catch (e: Exception) {
+            Logger.e("GroupAvatarUtils", "Failed to load vector drawable: $e")
+            return null
+        }
+    }
+}