Android如何优雅地解决重复Drawable资源

1. 前言

最近鸿洋大神和路遥大佬分别在他们的公众号上发布了关于解决Shape/Selector冗余的方案。这篇文章在上周末就已经写好了。虽然类似的解决方案特别多,实现思路也都差不多。但我仍然要安利一下我的这个解决方案。原因有以下几点。

  1. 很纯粹,就是用代码的方式实现了xml实现的Drawable,不用重写自定义View或者Hook系统的基础组件。
  2. 最大程度的复刻xml所拥有的能力,甚至连单位dp还是px的api都提供好了。
  3. 使用Builder模式将方法和参数都约束起来,使用起来很方便,不用去众多的api中寻找方法。结合Kotlin的语法,一个字“香”。
  4. 内部实现了缓存策略,以及根据Hash判重策略,这也是目前市面上的其他解决方案所没有的。

当然美中不足的是,目前所有的xml替换都是需要手工去完成,如果在编译期能够通过gradle插件自动转换,那就完美了。如果您有相关的经验,可以尝试一起把这个库做得更好。

2. Android为什么用xml生成Drawable


xml是Android系统中生成Drawable的首选方案,所以很多同学都习惯了使用xml生成GradientDrawable和SelectorDrawable,它们确实很方便。但是随之而来的问题,我相信很多同学都是深有体会的,哪怕是GradientDrawable中一个圆角大小的改动,或者一个颜色值的改动,都需要在原来的xml文件基础上拷贝一份新的xml文件,这样导致项目中的drawable文件越来越多。甚至一些编码规范没做好的团队,明明完全一样效果的drawable在项目中也有可能出现多份。

针对这种情况,有没有必要处理呢?大部分的xml文件也就1 2kb,占用空间很小,对包体积大小影响也没那么大。虽然说Android系统Drawable缓存是以文件名为维度的,但是它的回收策略做的挺棒的,冗余的xml对内存占用有影响,但没那么大。

那就任由文件数量膨胀吗?我觉得答案是见仁见智的,不处理也可以,无非就是写起来臃肿点呗,至少不用花时间去想一套解决方案。当然我们也可以精益求精,使用代码生成Drawable方案,实现与xml完全一样的效果,同时又能避免冗余的xml文件出现。

意外的收获👉 在项目使用svg作为图片时,发现在Android5.0 和Android6.0手机上,xml定义的selector图片显示不正常。究其原因是因为Android7.0以下不支持svg格式的fillType,导致selector渲染出来的图片有问题。想了很多方法都无法解决,最终通过代码生成selector的方案解决了。

在开始写通过代码生成Drawable之前,首先思考一个问题?为什么Android系统会首选xml生成Drawable方案呢?

通过分析xml渲染Drawable原理,我觉得系统兼容可能是使用xml的一个重要原因。以GradientDrawable的setPadding方法为例,该方法在Android Q版本引入。如果我们在xml文件引入padding,在Android Q以下版本也不会出问题。如果是代码中使用就需要做版本判断


闲话少叙,先看看最终的效果,下图左边是通过xml生成GradientDrawable,右边是通过代码生成GradientDrawable效果。

3. xml实现和代码实现


看下具体代码实现

  1. GradientDrawable xml实现

 

2. GradientDrawable代码实现

 

StateListDrawable xml实现

4. StateListDrawable 代码实现

addState(StatePressed)方法表示android:state_pressed=”true”

minusState(StatePressed)方法表示android:state_pressed=”false”

当然也可以添加多个状态

 

4. 特性以及源码


该库有以下特性:

  1. xml能实现的,它全部能实现
  2. 使用Builder模式,更容易构建Drawable
  3. 支持所有的android:state_xxx
  4. GradientDrawable,只要所有构建的参数内容一样(顺序可以打乱),内存中只会保留一份
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/20233,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?