本篇文章主要介绍以下几个知识点:

  • Drawable 简介
  • Drawable 的分类
  • 自定义 Drawable
hello,夏天 (图片来源于网络)

Drawable,使用简单,比自定义 View 成本低,非图片类型的 Drawable 占用空间小。

6.1 Drawable 简介

Drawable,一种图像的概念(不一定是图片,如通过颜色也可构造出图像)。

在 Android 设计中,Drawable 是一个抽象类,是所有 Drawable 对象的基类,其层次关系如下:

Drawable 的层次关系

通过 getIntrinsicWidthgetIntrinsicHeight 可获取 Drawable 的内部宽高。一张图片的宽高是其内部宽高,但一个颜色形成的 Drawable 没有内部宽高概念。(注:Drawable 的内部宽高不等同于其大小,一般是无大小概念,如作 View 的背景时会被拉伸至 View 的同等大小)

6.2 Drawable 的分类

Drawable 的种类繁多,如 BitmapDawableShapDrawableLayerDrawableStateListDrawable等。

6.2.1 BitmapDrawable

表示一张图片。实际开发中直接引用原始图片即可,也可通过 XML 的方式来描述,如下:

<?xml version="1.0" encoding="utf-8"?>

其中 gravity 属性的可选项如下:

gravity 属性的可选项

其中 tileMode 属性开启后各效果如下:

平铺模式下的图片显示效果

NinePatchDrawable,.9格式的图片,可自动根据所需的宽高进行相应的缩放而不失真,和 BitmapDrawable 一样,在实际开发中直接引用图片即可,也可通过 XML 来描述如下:

<?xml version="1.0" encoding="utf-8"?>

实际使用中在 bitmap 标签中也可用 .9 图,即 BitmapDrawable 也可代表一个 .9 格式的图片。

6.2.2 ShapeDrawable

通过颜色来构造的图形,可以是纯色的图形,也可以是具有渐变效果的图形。其语法如下:

<?xml version="1.0" encoding="utf-8"?>                                                

其中 shape 属性中的 ring 这个形状,有 5 个特殊属性如下:

ring 的属性值

其中 type 属性各类别的区别如下:

渐变的类别,从左到右依次为 linear、radial、sweep

6.2.3 LayerDrawable

其对应的 XML 标签是,表示一种层次化的 Drawable 集合,一种叠加的效果,其语法如下:

<?xml version="1.0" encoding="utf-8"?>            

下面是一个 layer-list 具体使用例子,它实现了微信中的文本输入框效果,代码如下:

                                                                                                            

运行效果如下:

layer-list 的应用

6.2.4 StateListDrawable

其对应的 XML 标签是,也是表示 Drawable 集合,每个 Drawable 对应着 View 的一种状态,其语法如下:

<?xml version="1.0" encoding="utf-8"?>        

其中 标签中的 View 的常见状态如下:

View 的常见状态

StateListDrawable 主要用于设置可单击的 View 的背景,如 Button,常见的例子如下:

                

6.2.5 LevelListDrawable

其对应的 XML 标签是,也是表示 Drawable 集合,每个 Drawable 都有一个等级的概念。LevelListDrawable 根据不同的等级切换对应的 Drawable,其语法如下:

        

LevelListDrawable 作为 View 的背景时可通过 Drawable 的 setLevel 来设置不同的等级,作为 ImageView 的前景时可通过 ImageView 的 setImageLevel 来切换 Drawable。

Drawable 等级范围为 0 ~ 10000,例子如下:

        

6.2.6 TransitionDrawable

其对应的 XML 标签是,用于实现两个 Drawable 之间的淡入淡出效果,其语法如下:

        

使用步骤如下:

1. 定义 TransitionDrawable

        

2. 设置为 View 的背景

3. 通过startTransitionreverseTransition 来开启效果及其逆过程

TextView tvTransition = (TextView) findViewById(R.id.tv_transition);TransitionDrawable drawable = (TransitionDrawable) tvTransition.getBackground();drawable.startTransition(2000);

运行效果如下:

transition 效果

6.2.7 InsetDrawable

其对应的 XML 标签是,可以将其他 Drawable 内嵌到自己当中,并可在四周留出一定的间距,其语法如下:

当一个 View 的背景比自己的实际区域小时可采用 InsetDrawable 实现(也可采用 LayerDrawable 来实现),如下:

                

运行效果:

InsetDrawable 效果

6.2.8 ScaleDrawable

其对应的 XML 标签是,它可以根据自己的等级(level)将指定的 Drawable 缩放到一定比例,其语法如下:

ScaleDrawable 的默认等级为 0,即不可见,要 ScaleDrawable 可见则等级不为 0。如将一张图片缩小为原来的30%,如下:

然后设置 ScaleDrawable 的等级大于 0且小等于10000的值,如下:

TextView tvScale = (TextView) findViewById(R.id.tv_scale);ScaleDrawable scaleDrawable = (ScaleDrawable) tvScale.getBackground();scaleDrawable.setLevel(1);

6.2.9 ClipDrawable

其对应的 XML 标签是,它可以根据自己的等级(level)来剪裁另一个Drawable,其语法如下:

其中 gravity 的属性如下:

ClipDrawable 的 gravity 属性

下面实现将一张图片从上往下进行裁剪的效果:

1. 定义 ClipDrawable

   

2. 设置给 ImageView (也可作为 View 的背景)

 

3. 在代码中设置 ClipDrawable 的等级

ImageView ivClip = (ImageView) findViewById(R.id.iv_clip);ClipDrawable clipDrawable = (ClipDrawable) ivClip.getDrawable();// 0-10000,其中0表示完全裁剪,10000表示不裁剪clipDrawable.setLevel(5000);

运行效果如下:

ClipDrawable 的裁剪效果

6.3 自定义 Drawable

Drawable 使用范围单一,作为 ImageView 的图像显示或者作为 View 的背景。

Drawable 的工作原理很简单,其核心是 draw 方法,可通过重写其 draw 方法来自定义 Drawable。(注:自定义的 Drawable 无法在 XML 中使用)

下面自定义一个圆形的 Drawable,它的半径会随着 View 的变化而变化,可作为 View 的通用背景,如下:

public class CustomDrawable extends Drawable {    private Paint mPaint;    public CustomDrawable(int color) {        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(color);    }    @Override    public void draw(@NonNull Canvas canvas) {        final Rect r = getBounds();        float cx = r.exactCenterX();        float cy = r.exactCenterY();        canvas.drawCircle(cx, cy ,Math.min(cx, cy), mPaint);    }    @Override    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {        mPaint.setAlpha(alpha);        invalidateSelf();    }    @Override    public void setColorFilter(@Nullable ColorFilter colorFilter) {        mPaint.setColorFilter(colorFilter);        invalidateSelf();    }    @Override    public int getOpacity() {        // not sure, so be safe        return PixelFormat.TRANSLUCENT;    }}

在代码中设置自定义的 Drawale:

ImageView ivCustom = (ImageView) findViewById(R.id.iv_custom_drawable);CustomDrawable customDrawable = new CustomDrawable(getResources().getColor(R.color.colorAccent));ivCustom.setImageDrawable(customDrawable);

运行效果如下:

自定义圆形的 Drawable

以上便是完整的自定义 Drawable 的流程。值得注意的是,自定义的 Drawable 有固定大小时最好重写 getIntrinsicWidthgetIntrinsicHeight 这两方法。

本篇文章就介绍到这。

更多相关文章

  1. Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图
  2. 关于android4.0.4中彩蛋的实现
  3. android animation之scale 缩放(仿微信加号弹出菜单的动画效果)
  4. Android回部古剑之ViewFlipper之仙人指路
  5. Android之如果解决Android(安卓)studio项目里面的类名不能重命名
  6. Android动态模糊效果的快速实现方法
  7. Android仿微信图片编辑处理:文字,马赛克,裁剪,涂鸦,旋转图片等
  8. android 背景图片滚动
  9. android加载大图推荐框架LargeImageView及所遇问题——部分机型

随机推荐

  1. css选择器与权重
  2. 伪类选择器与盒模型属性实例解析,附字体
  3. 伪类选择器、字体图标、盒模型属性、em和
  4. 12月22日作业 task1表格
  5. 注册表(原始的未加 css)
  6. 课程表(报名表)
  7. css样式 来源 规则 选择器权重
  8. Emmet语法
  9. css伪类选择器,字体图标,盒模型及自适应布
  10. Linux系统配置(系统优化)