Android Drawable代码编写的新姿势分享

目录
  • 概念
  • 优点
  • 表现形式
  • 直接子类与非直接子类
  • xml解析流程
  • 真实案例
  • 更好的实现方式 —代码
  • 建议
  • 优点
  • 引用方式
  • 总结

概念

Drawable表示一种可以在Canvas上进行绘制的抽象的概念,它有很多种,常见的如颜色和图片都可以是一个Drawable。

优点

  • 首先,它的使用比较简单,在xml里已经定义了大量的属性方法,我们只要熟悉各个属性的ui效果和特点就可以自己组合各种的界面效果。
  • 其次,它的实现成本比自定义View低,一些比较简单的、定制性、重复性的UI效果使用drawable将会缩小开发成本。但是一些比较复杂的ui场景,drawable却表现不出自定义view的那种效果。
  • 相比较于图片而言,drawable占用空间更小,这样有利于缩小apk的体积。

表现形式

Drawable尽管对于应用程序通常不可见,但Drawable可以采用多种形式:

Bitmap:最简单的Drawable,一个PNG或JPEG图像。

Nine Patch:是对PNG格式的扩展允许它指定如何对其进行拉伸和放置的信息

Vector:向量:在XML文件中定义的可绘制的一组点,线和曲线以及相关的颜色信息。 这种类型的绘图可以缩放而不会损失显示质量。

Shape:形状:包含简单的绘图命令而不是原始位图,允许在某些情况下调整更好。

Layers:图层:一个可绘制的复合物,它在彼此顶部绘制多个底层可绘图。

States:状态,一个复合drawable,根据其状态选择一组drawable中的一个。

Levels:级别:一个复合drawable,根据其级别从一组drawable中选择一个。

Scale:比例尺:一个可绘制的单个子组合可绘制的组合,其整体大小根据当前级别进行修改。

直接子类与非直接子类

xml解析流程

最终的inflateFromTag方法

  @NonNull
    @SuppressWarnings("deprecation")
    private Drawable inflateFromTag(@NonNull String name) {
        switch (name) {
            case "selector":
                return new StateListDrawable();
            case "animated-selector":
                return new AnimatedStateListDrawable();
            case "level-list":
                return new LevelListDrawable();
            case "layer-list":
                return new LayerDrawable();
            case "transition":
                return new TransitionDrawable();
            case "ripple":
                return new RippleDrawable();
            case "adaptive-icon":
                return new AdaptiveIconDrawable();
            case "color":
                return new ColorDrawable();
            case "shape":
                return new GradientDrawable();
            case "vector":
                return new VectorDrawable();
            case "animated-vector":
                return new AnimatedVectorDrawable();
            case "scale":
                return new ScaleDrawable();
            case "clip":
                return new ClipDrawable();
            case "rotate":
                return new RotateDrawable();
            case "animated-rotate":
                return new AnimatedRotateDrawable();
            case "animation-list":
                return new AnimationDrawable();
            case "inset":
                return new InsetDrawable();
            case "bitmap":
                return new BitmapDrawable();
            case "nine-patch":
                return new NinePatchDrawable();
            case "animated-image":
                return new AnimatedImageDrawable();
            default:
                return null;
        }
    }

真实案例

shape count radio
shape 833 73%
selector 240 21%
layer-list 50  
animated-rotate 7  
animation-list 5  
vector 3  
rotate 2  
level-list 1  

我的项目里面,统计了drawable文件的总数是1140, 其中最多的是shape,总数833,占比73%, 其次是selector,总数240,占比21%, 这两个加起来占比达到94%. 而这两种类型都是差别很小的,主要是背景颜色和圆角角度不同,导致了大量的文件的产生, 而且对于这类的文件命名也是很难统一,从而难以达到复用的效果,有时候找一个目标文件, 远远没有自己创建一个新的Drawable文件快,所以渐渐的会导致此类文件的爆炸式增长。 从而增大apk的体积。

通过xml解析流程,我们可以发现其中的奥妙,xml也只是根据具体的标签直接new出来对应的是类,然后再直接设置具体的参数, 如此一来,我们完全可以做到,自己创建具体的对象,然后设置参数,这样就避免了xml解析这一步,

更好的实现方式 —代码

      mViewBinding.lineDrawable.background = shapeDrawable(this) {
            lineShape()
            dash(10, 5)
            strokeColor(Color.RED)
            strokeWidth(2)
        }

      mViewBinding.stateListDrawable.background = selectorDrawable {

          pressedDrawable {
                shapeDrawable(this@MainActivity) {
                    solidColor(Color.BLUE)
                    radius(8)
                }
          }

          defaultDrawable {
                shapeDrawable(this@MainActivity) {
                    solidColor(Color.GRAY)
                    radius(8)
                }
          }
      }

建议

具体的项目可以在封装一次,减少每次的创建条件设置,这样只需要传递具体的参数就可以,便于复用, 当然,项目也封装了几个通用的方法。比如:

    fun shapeDrawableColorInt(context: Context, @ColorInt colorInt: Int = Color.WHITE, radius: Int = 0) =
        shapeDrawable(context) {
            solidColor(colorInt)
            radius(radius)
    }

    fun shapeDrawableColorRes(context: Context, @ColorRes colorRes: Int, radius: Int = 0) =
        shapeDrawable(context) {
            solidColorRes(colorRes)
            radius(radius)
    }

优点

比起xml方式可以提升性能:

  • 避免xml解析流程
  • 复用这些代码
  • 比xml管理方便

引用方式

github地址

       implementation 'io.github.weiggle:drawable:1.0.1'

总结

到此这篇关于Android Drawable代码编写的新姿势的文章就介绍到这了,更多相关Android Drawable代码编写内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android对图片Drawable实现变色示例代码

    前言 本文主要给大家介绍了Android中图片DrawableCompat利用setTint()对图片Drawable进行变色的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 1.利用color资源对Drawable变色 Drawable对象的来源不限制,可以是从资源getResource().getDrawable(int resourceId)也可以是其他的方式得到的Drawable Drawable wrappedDrawable = DrawableCompat

  • Android Bitmap和Drawable相互转换的简单代码

    很多开发者表示,不知道Android的Drawable和Bitmap之间如何相关转换.下面Android123给大家两种比较简单高效的方法. 一.Bitmap转Drawable 复制代码 代码如下: Bitmap bm=xxx; //xxx根据你的情况获取 BitmapDrawable bd=BitmapDrawable(bm); Android开发网提示因为BtimapDrawable是Drawable的子类,最终直接使用bd对象即可. 二. Drawable转Bitmap 转成Bitmap对

  • Android Drawable代码编写的新姿势分享

    目录 概念 优点 表现形式 直接子类与非直接子类 xml解析流程 真实案例 更好的实现方式 —代码 建议 优点 引用方式 总结 概念 Drawable表示一种可以在Canvas上进行绘制的抽象的概念,它有很多种,常见的如颜色和图片都可以是一个Drawable. 优点 首先,它的使用比较简单,在xml里已经定义了大量的属性方法,我们只要熟悉各个属性的ui效果和特点就可以自己组合各种的界面效果. 其次,它的实现成本比自定义View低,一些比较简单的.定制性.重复性的UI效果使用drawable将会缩

  • NET Core 3.0 AutoFac内置DI替换的新姿势分享

    .NET Core 3.0 和 以往版本不同,替换AutoFac服务的方式有了一定的变化,在尝试着升级项目的时候出现了一些问题. 原来在NET Core 2.1时候,AutoFac返回一个 IServiceProvider 参数注入到ConfigureServices .NET Core 服务中,基本大痣是这样做的. 首先我们需要一个重写 Autofac.Module 的方法,这将用于将我们 Register [数据访问层] 以及 Services [逻辑层] 的注册. public class

  • Python只用40行代码编写的计算器实例

    本文实例讲述了Python只用40行代码编写的计算器.分享给大家供大家参考,具体如下: 效果图: 代码: from tkinter import * reset=True def buttonCallBack(event): global label global reset num=event.widget['text'] if num=='C': label['text']="0" return if num in "=": label['text']=str(

  • Android组件WebView编写有道词典小案例分享

    最近学习了WebView组件,写了一个有道词典的小案例,分享给大家,供大家参考,具体内容如下 效果图: 源码下载:https://coding.net/u/gxs1225/p/YouDaoDictionary/git 代码如下: 布局 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schema

  • Python代码一键转Jar包及Java调用Python新姿势

    需求背景 进击的Python 随着人工智能的兴起,Python这门曾经小众的编程语言可谓是焕发了第二春. 以tensorflow.pytorch等为主的机器学习/深度学习的开发框架大行其道,助推了python这门曾经以爬虫见长(python粉别生气)的编程语言在TIOBE编程语言排行榜上一路披荆斩棘,坐上前三甲的宝座,仅次于Java和C,将C++.JavaScript.PHP.C#等一众劲敌斩落马下. 当然,轩辕君向来是不提倡编程语言之间的竞争对比,每一门语言都有自己的优势和劣势,有自己应用的领

  • J2EE项目代码编写规范分享

    码编写规范目的:能够在编码过程中实现规范化,为以后的程序开发中养成良好的行为习惯. 代码编写规范使用范围:J2EE项目开发. 包命名规范: 目的:包的命名规范应当体现出项目资源良好的划分 servlet类所在包命名规范:公司名称.开发组名称.项目名称.web.servlet 例如:net.linkcn.web.servlet 自定义标签类所在包命名规范:公司名称.开发组名称.项目名称.web.tags 例如:net.linkcn.web.tags 过滤器类所在包命名规范:公司名称.开发组名称.项

  • 30条Java代码编写经验分享

    成为一个优秀的Java程序员,有着良好的代码编写习惯是必不可少的.下面就让我们来看看代码编写的30条建议吧. (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsMethodOrFieldName 若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母.这样便可标志出它们属于编译期的常数. Java包(Package

  • JAVASCRIPT代码编写俄罗斯方块网页版

    俄罗斯方块方块是小时候的一个回忆,从最开始的掌上的黑白游戏机,到电视游戏机,到电脑,无不有它的痕迹,今天我们来一起重温它的一种实现方法,也算是整理一下我的思路吧...... HTML+CSS+JS实现俄罗斯方块完整版,素材只有图片,想要的下载图片按提示名字保存,css中用的时候注意路径!!主要在JS中!JS附有详细注释 效果: 按键提示:[键盘按键] 素材:图片名字与代码里对应 1.背景图片:tetris.png 2.失败时候的弹出框图片:game-over.png 3.七种色彩小方块图片:  

  • Android 谷歌推荐的VR实现方式(分享)

    谷歌有专门的SDK来完成VR,我这次以一个全景图片的例子来说一下这个SDK实现VR的基本过程,首先全景图片就是百度地图里的那样,能够看到周围环境360的图片. 添加依赖 compile 'com.google.vr:sdk-panowidget:1.80.0' 添加权限 <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="an

  • Android Studio 3.6中新的视图绑定工具ViewBinding 用法详解

    前言 我们在Android开发的过程中总是需要获取XML布局中的ViewId,以便给其赋值进行显示,早期我们只能使用 findViewById 这个API,会导致很多的模版代码出现.2013年左右Android界大神 Jake Wharton开源了Butter Knife框架,通过Bind("viewid")方式方便开发者获取ViewId.近两年由于谷歌对Kotlin的支持,我们开始使用 Android Kotlin extensions. 在文件中导入布局文件直接引用viewId.无

随机推荐