Android | 通过 layer-list 设置默认加载错误图片

背景

在需求开发中,经常会遇到需要展示图片列表的情况。然而,由于网络问题、图片链接失效等原因,某些图片可能无法正常加载。为了优化用户体验,通常会为加载失败的图片提供一个默认的占位图。

在常规的实现方式中,可能会直接使用一张默认图片来作为占位图(如果是个单色图,可以直接用一个drawable文件)。然而,如果图片列表里每个Item宽高比都是变化的时候,默认图片会因为宽高比不同而导致变形,虽然可以通过 ImageView 的 scaleType 设置 CENTER_CROP 以适应不同的图片比例不变形,但如果默认图片本身包含一个居中的小图标,在不同的宽高比下,小图标的显示效果可能会变形或错位。

问题分析

假设我们的默认错误图片是如下所示的样式(背景色 + 一个居中的错误图标):

如果我们将其合成一张完整的 PNG 图片并使用 CENTER_CROP 适配不同的 ImageView 尺寸,可能会遇到两个问题: 1. 小图标会跟随图片裁剪,可能会放大、变形,导致显示不一致。 2. 不同比例的 ImageView 会截取不同区域,导致小图标的位置和大小不可控。

为了解决这个问题,可以换一种思路,利用 layer-list 来动态组合背景和图标,从而确保小图标始终保持固定大小和居中位置。

解决方案:使用 layer-list

在 drawable 资源中,layer-list 允许我们叠加多个图层,可以将背景和图标分开定义,保证不同尺寸的 ImageView 显示时,背景始终铺满,而小图标始终居中,且不会因裁剪而变形。其中小图片的资源如下:

  • 创建 layer-list 资源文件

在 res/drawable/ 目录下创建 drawable_default_error.xml:

kotlin 复制代码
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 背景矩形 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/gray_normal" /> <!-- 设置背景颜色 -->
        </shape>
    </item>

    <!-- 居中的错误图标 -->
    <item
        android:width="60dp"
        android:height="60dp"
        android:gravity="center">
        <bitmap
            android:gravity="center"
            android:src="@drawable/chat_ask_message_error" />
    </item>
</layer-list>
  • 代码中使用 layer-list

在使用 Glide 或其他图片加载框架时,我们可以直接将 drawable_default_error.xml 作为 placeholder 和 error 资源:

kotlin 复制代码
Glide.with(activity)
    .load(url)
    .placeholder(R.drawable.drawable_default_error) // 加载中显示的占位图
    .error(R.drawable.drawable_default_error) // 加载失败时显示的默认图
    .into(imageView)

效果展示

当图片加载失败时,ImageView 会显示 drawable_default_error.xml 组合的背景 + 图标,效果如下:

相比直接使用一张完整的 PNG 图片,layer-list 方案的优点:

  • 保证背景始终填充整个 ImageView,不会因为 scaleType 而变形。
  • 小图标始终保持固定大小,居中不变形,适应不同的 ImageView 尺寸。
  • 支持动态调整背景色或小图标,无需重新制作整张图片,维护更方便。

总结

在 Android 开发中,layer-list 是一个非常实用的 Drawable 资源,它可以将多个层叠的图形、颜色、图片等组合在一起,实现复杂的视觉效果。在需要为加载失败的图片提供占位图时,使用 layer-list 可以保证背景填充、图标居中且不会变形。

相关推荐
阿巴斯甜17 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker18 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952719 小时前
Andorid Google 登录接入文档
android
黄林晴20 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android