Android bitmap标签用法 XML中对图片进行平铺或抗锯齿

1次阅读

要实现图片平铺,必须使用带tilemode=”repeat”的bitmap drawable资源(如res/drawable/bg_tile.xml),而非直接在imageview中用android:src或android:background;api 23+才支持xml中设置tilemode,低版本需代码调用mutate()后设tilemodex/y。

Android bitmap标签用法 XML中对图片进行平铺或抗锯齿

android:src 和 android:background 都不能直接平铺图片

XML 中用 android:srcandroid:background 引入一张 Bitmap,默认是拉伸或居中显示,不是平铺。想实现平铺(tiling),必须换思路:用 BitmapDrawable 配合 tileMode,且只能通过代码或 XML 定义 drawable 资源来实现。

  • 直接在 ImageView 的 XML 里写 android:background="@drawable/xxx" 是可行的,但前提是 @drawable/xxx 是一个带 tileModebitmap 标签定义
  • tileMode 只支持 "disabled""clamp""repeat""mirror",常用的是 "repeat"
  • 注意:API 23+ 才支持在 XML 中直接写 tileMode;低版本必须用代码设置 setTileModeX/setTileModeY
  • 平铺对性能影响不大,但若图片本身分辨率高、又没做尺寸裁剪,可能触发大量重复绘制,建议用小尺寸图(如 8×8 或 16×16 像素)作为平铺单元

XML 中用 bitmap 标签开启平铺和抗锯齿

bitmapdrawable 资源的一种 XML 形式,支持 tileModeantialias,但它不是直接写在布局 XML 里,而是单独放在 res/drawable/ 下,再被引用。

  • 新建文件 res/drawable/bg_tile.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android"     android:src="@drawable/pattern_dot"     android:tileMode="repeat"     android:antialias="true" />
  • android:antialias="true" 对 bitmap 边缘做抗锯齿,仅在缩放或旋转时生效;静态展示下几乎看不出差别,但配合 scaleType="matrix" 或动画时有用
  • android:dither="true"(可选)能改善颜色过渡带状感,尤其在低端屏上,但会略微增加内存开销
  • 这张 @drawable/pattern_dot 必须是 PNG,且推荐无透明通道或 Alpha 清晰——带半透边缘的图在平铺时容易出现接缝色差

Java/kotlin 代码中动态启用 tileMode 更灵活

XML 方式受限于 API 级别和复用场景,实际开发中常需要运行时切换平铺开关或调整模式,这时必须用代码。

  • 获取背景 drawable 后强转为 BitmapDrawable,再调用 getBitmap() 获取原图
  • 不能直接对 BitmapDrawablesetTileModeX,得先用 mutate() 防止共享状态污染
  • 正确写法(Kotlin 示例):
val drawable = imageView.background if (drawable is BitmapDrawable) {     val mutated = drawable.mutate()     (mutated as BitmapDrawable).tileModeX = Shader.TileMode.REPEAT     (mutated as BitmapDrawable).tileModeY = Shader.TileMode.REPEAT }
  • 注意:mutate() 必须在设 tileMode 前调用,否则无效;且只对当前实例生效,不影响其他引用同一资源的地方
  • 如果图片来自网络或 Asset,需先解码为 Bitmap,再构建 BitmapDrawable,此时 antialias 要靠 Paint.setAntiAlias(true) 在自定义 Drawable 中控制

常见错误:平铺不生效或锯齿明显

最常遇到的两个现象:图片只显示一次、边缘毛刺严重。根本原因往往不在参数本身,而在资源或使用链路上。

  • 平铺不生效 → 检查是否误把 bitmap XML 放在 res/drawable-v24/ 下导致低版本加载失败,回退到默认 drawable;统一放 res/drawable/
  • 锯齿明显 → antialias="true" 不起作用?确认该 drawable 是否被套在 layer-liststate-list 中——嵌套层级过深时,父容器可能覆盖子项的抗锯齿设置
  • ImageView 设置了 scaleType="centerCrop""fitXY",会破坏平铺逻辑,必须用 "matrix" 或保持默认(即不设)
  • android studio 预览 XML 时,平铺可能不渲染,这是预览器限制,真机或模拟器才真实生效

真正要小心的是 tileMode 和 antialias 的组合效果依赖底层 Skia 渲染路径,不同 Android 版本行为略有差异,尤其是 Android 7.0 之前对 mirror 模式支持不完整。测的时候别只看一个机型。

text=ZqhQzanResources