LayerDrawable无法显示4张图片仅显示一张的技术问题求助
Android中LayerDrawable仅显示单张图片的问题
我在Android开发中尝试用LayerDrawable显示4张图片,但始终只有一张能正常显示。以下是核心实现代码和布局文件:
核心代码
private fun getClusterIcon(cluster: Cluster<Store>): BitmapDescriptor? { val profilePhotos: MutableList<Drawable> = ArrayList(4.coerceAtMost(cluster.size)) for(store in cluster.items) { if (profilePhotos.size == 4) break; Picasso.get().load(store.hauptBild).into(object : com.squareup.picasso.Target { override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { val drawable: Drawable = BitmapDrawable(ctx.resources,bitmap); drawable.setBounds(0, 0, width, height) profilePhotos.add(drawable) } override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {} override fun onPrepareLoad(placeHolderDrawable: Drawable?) {} }) } val multiDrawable = LayerDrawable(profilePhotos.toTypedArray()) multiDrawable.setBounds(0, 0, width, height) mClusterImageView!!.setImageDrawable(multiDrawable) val icon: Bitmap = mClusterIconGenerator.makeIcon(cluster.size.toString()) return BitmapDescriptorFactory.fromBitmap(icon) }
布局文件(multi_profil.xml)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="2dp" android:layout_width="@dimen/custom_profile_image" android:layout_height="@dimen/custom_profile_image"> <ImageView android:id="@+id/image" android:scaleType="centerCrop" android:layout_width="@dimen/custom_profile_image" android:layout_height="@dimen/custom_profile_image"/> <TextView android:id="@id/amu_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/amu_Bubble.TextAppearance.Light" android:background="@android:color/black" android:paddingLeft="@dimen/custom_profile_padding" android:paddingRight="@dimen/custom_profile_padding" android:layout_gravity="center" android:alpha=".8"/> </FrameLayout>
问题原因
- Picasso异步加载时序错误:
into(Target)是异步操作,循环结束后立刻创建LayerDrawable时,profilePhotos列表大概率还没加载完所有图片,导致LayerDrawable中Drawable数量不足。 - Drawable边界重叠:所有Drawable的
bounds都设置为(0, 0, width, height),四张图完全重叠,视觉上只能看到最上层的一张。
解决方案
1. 处理异步加载时序
用CountDownLatch等待所有图片加载完成后再创建LayerDrawable,同时避免主线程阻塞:
private fun getClusterIcon(cluster: Cluster<Store>) { val maxCount = 4.coerceAtMost(cluster.size) val profilePhotos: MutableList<Drawable> = ArrayList(maxCount) val latch = CountDownLatch(maxCount) for(store in cluster.items) { if (profilePhotos.size == maxCount) break Picasso.get().load(store.hauptBild).into(object : com.squareup.picasso.Target { override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { bitmap?.let { val drawable = BitmapDrawable(ctx.resources, it) profilePhotos.add(drawable) } latch.countDown() } override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) { latch.countDown() } override fun onPrepareLoad(placeHolderDrawable: Drawable?) {} }) } Thread { try { latch.await() ctx.runOnUiThread { if (profilePhotos.isEmpty()) return@runOnUiThread val multiDrawable = LayerDrawable(profilePhotos.toTypedArray()) multiDrawable.setBounds(0, 0, width, height) // 分区域设置每张图的边界,避免重叠 val halfW = width / 2 val halfH = height / 2 profilePhotos.forEachIndexed { index, _ -> val drawable = multiDrawable.getDrawable(index) when(index) { 0 -> drawable.setBounds(0, 0, halfW, halfH) 1 -> drawable.setBounds(halfW, 0, width, halfH) 2 -> drawable.setBounds(0, halfH, halfW, height) 3 -> drawable.setBounds(halfW, halfH, width, height) } } mClusterImageView!!.setImageDrawable(multiDrawable) val icon = mClusterIconGenerator.makeIcon(cluster.size.toString()) // 这里可通过回调或LiveData传递生成的BitmapDescriptor } } catch (e: InterruptedException) { e.printStackTrace() } }.start() }
2. 调整返回逻辑
原方法直接返回BitmapDescriptor会因异步加载未完成返回空值,建议改用回调接口或LiveData传递最终结果,替代直接返回值的方式。
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

