安卓Drawable分类

基于你提供的详尽分类框架,我结合最新实践补充底层原理、实用技巧及进阶用法,帮助开发者更系统化地掌握 Drawable 体系:


⚙️ ​一、底层机制与核心原理

  1. Drawable 基类关键方法

    • draw(Canvas canvas):抽象绘制方法,所有子类必须实现(如 BitmapDrawable 绘制位图、ColorDrawable 填充纯色)
    • setBounds(Rect bounds):定义绘制区域,触发 onBoundsChange() 回调
    • setLevel(int level):控制动态效果(如 ClipDrawable 裁剪比例)
    • setState(int[] stateSet):响应视图状态变化(如 StateListDrawable 的按下/聚焦状态)
  2. 资源复用与性能优化

    • 共享资源BitmapDrawable 默认共享位图资源,调用 mutate() 可创建独立副本避免相互影响
    • 自动压缩 :AAPT 工具会优化 res/drawable 中的 PNG 图片(如 256 色转 8 位),若需原图应放 res/raw/

🎨 ​二、进阶分类与使用场景扩展

类别 核心子类 最佳实践
基础图形 ColorDrawable 纯色背景,优先用 @color 资源而非硬编码
ShapeDrawable 矩形/圆角/描边,替代简单图片减少资源体积
GradientDrawable 支持线性/径向/扫描渐变,替代渐变图片
动态响应 StateListDrawable 状态顺序敏感!​从上到下匹配,首个匹配项生效(默认状态应放最后)
RippleDrawable 水波纹效果需嵌套 <item> 定义背景,避免遮盖内容
组合变换 LayerDrawable 图层顺序=绘制顺序,​最后一项显示在最顶层
InsetDrawable 为其他 Drawable 添加内边距,避免文本贴边
ClipDrawable 进度条首选!level 范围 0(全剪)~10000(全显)
矢量与动画 VectorDrawable 图标首选,适配多分辨率屏幕,需兼容库支持 API <21
AnimatedVectorDrawable 路径变形动画,结合 <target> 指定动画作用对象

⚡️ ​三、高频问题解决方案

  1. ​**.9 图片使用规范**​

    • 必须放 res/drawable/mipmap/ 目录无效
    • AS 要求保留黑边(反编译 APK 获取带黑线的原图)
  2. 动态创建技巧

    ini 复制代码
    // 代码创建渐变按钮背景
    val gradient = GradientDrawable().apply {
      shape = GradientDrawable.RECTANGLE
      cornerRadius = 16.dpToPx() // 转换 dp 为像素
      colors = intArrayOf(Color.BLUE, Color.CYAN)
    }
    button.background = gradient
  3. 性能陷阱规避

    • 避免嵌套超过 3 层的 StateListDrawable
    • 复杂图形用 VectorDrawable 替代多张位图

🛠️ ​四、XML 实战示例:带按压效果的渐变按钮

xml 复制代码
<!-- res/drawable/btn_gradient_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按压状态:深色渐变 -->
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <gradient
                android:startColor="#FF416C"
                android:endColor="#FF4B2B"
                android:angle="45"/>
        </shape>
    </item>
    <!-- 默认状态:亮色渐变 -->
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <gradient
                android:startColor="#36D1DC"
                android:endColor="#5B86E5"
                android:angle="45"/>
        </shape>
    </item>
</selector>

通过 android:angle 控制渐变方向,state_pressed 区分状态


💎 ​总结建议

  • 优先矢量 :图标/简单图形用 VectorDrawable,减少分辨率适配成本
  • 慎用位图 :复杂图片选 WebP 格式,.9.png 用于特殊拉伸需求
  • 状态精简StateListDrawable 的状态匹配链尽量简短
  • 组合创新LayerDrawable + ClipDrawable 可实现动态进度条+背景叠加

更多实践案例可参考 Android Developers 官方资源 或 菜鸟教程示例。

相关推荐
molong9311 天前
Android 应用配置跳转微信小程序
android·微信小程序·小程序
2501_915106321 天前
iOS 可分发是已经上架了吗?深入解析应用分发状态、ipa 文件上传、TestFlight 测试与 App Store 审核流程
android·ios·小程序·https·uni-app·iphone·webview
安东尼肉店1 天前
Android compose屏幕适配终极解决方案
android
2501_916007471 天前
HTTPS 抓包乱码怎么办?原因剖析、排查步骤与实战工具对策(HTTPS 抓包乱码、gzipbrotli、TLS 解密、iOS 抓包)
android·ios·小程序·https·uni-app·iphone·webview
feiyangqingyun1 天前
基于Qt和FFmpeg的安卓监控模拟器/手机摄像头模拟成onvif和28181设备
android·qt·ffmpeg
用户2018792831672 天前
ANR之RenderThread不可中断睡眠state=D
android
煤球王子2 天前
简单学:Android14中的Bluetooth—PBAP下载
android
小趴菜82272 天前
安卓接入Max广告源
android
齊家治國平天下2 天前
Android 14 系统 ANR (Application Not Responding) 深度分析与解决指南
android·anr
ZHANG13HAO2 天前
Android 13.0 Framework 实现应用通知使用权默认开启的技术指南
android