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 可以保证背景填充、图标居中且不会变形。

相关推荐
百锦再37 分钟前
Java与Kotlin在Android开发中的全面对比分析
android·java·google·kotlin·app·效率·趋势
Ya-Jun4 小时前
常用第三方库:flutter_boost混合开发
android·flutter·ios
_一条咸鱼_6 小时前
深度剖析:Android NestedScrollView 惯性滑动原理大揭秘
android·面试·android jetpack
_一条咸鱼_6 小时前
深度揭秘!Android NestedScrollView 绘制原理全解析
android·面试·android jetpack
_一条咸鱼_6 小时前
揭秘 Android CoordinatorLayout:从源码深度解析其协同工作原理
android·面试·android jetpack
_一条咸鱼_6 小时前
揭秘 Android View 的 TranslationY 位移原理:源码深度剖析
android·面试·android jetpack
_一条咸鱼_6 小时前
揭秘 Android NestedScrollView 滑动原理:源码深度剖析
android·面试·android jetpack
_一条咸鱼_6 小时前
深度揭秘:Android NestedScrollView 拖动原理全解析
android·面试·android jetpack
_小马快跑_6 小时前
重温基础:LayoutInflater.inflate(resource, root, attachToRoot)参数解析
android
_一条咸鱼_6 小时前
揭秘!Android RecyclerView 预取(Prefetch)原理深度剖析
android·面试·android jetpack