详解Android Drawable

本文详细介绍了Android中的Drawable,包括Drawable的概述、子类、自定义Drawable及其State,讲解了Drawable在View尺寸计算中的作用,以及如何自定义复杂的效果,如自定义StateListDrawable在Spinner中的应用。
摘要由CSDN通过智能技术生成

1 Drawable概述

Drawable是一种图像的概念,但又不全是图片,也可能是各种颜色组合而成的图像。通常将Drawable作为View的背景,而这些Drawable我们一般通过XML来定义,当然也可以通过代码来实现,但是并没有XML来得方便。Drawable是一个抽象类,其子类有我们熟悉的BitmapDrawable等。
Drawable内部有固有宽高的概念,通过getIntrinsicWidthgetIntrinsicHeight来获得,然而并不是所有的drawable都有这两个值,BitmapDrawable这两个值的大小是图片的宽高,而单纯以颜色形成的Drawable的这两个值一般都是-1(不过是可以修改的)。但是注意,这两个值并不代表Drawable的宽高,一般而言Drawable没有宽高的概念,当用作背景的时候,Drawable会被拉伸到View的同等大小(注意:只是一般而言,存在特例,请看下文)。
那么IntrinsicWidth和IntrinsicHeight有什么用呢?还记得在View的默认的onMeasure方法吗?

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
            getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

当Spec的mode为UNSPECIFIED时,getDefaultSize会以getSuggestedMinimumWidth()的返回值作为View的大小。

protected int getSuggestedMinimumWidth() {
    return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}

而Drawable的getMinimumWidth()方法如下:

public int getMinimumWidth() {
    final int intrinsicWidth = getIntrinsicWidth();
    return intrinsicWidth > 0 ? intrinsicWidth : 0;
}

总结一下就是,View默认的onMeasure方法在MeasureSpec为UNSPECIFIED时,会以背景Drawable的IntrinsicWidth和IntrinsicHeight作为宽和高,如果没有背景就以XML中设定的minWidth和minHeight作为宽高。
当然这只是默认的onMeasure方法了,而且还是UNSPECIFIED这么不常见的情况。但其实getSuggestedMinimumWidth这个方法在很多View的子类(比如说ImageView,TextView等)的重载的onMeasure方法中都有调用,用来作为View尺寸的下限,可以说应用的还是蛮普遍的。
另外注意一点,图片的IntrinsicWidth和IntrinsicHeight的值是已经按照图片所在的文件夹(drawable-mdpi,drawable-hdpi,drawable-xhdpi这些)和手机的像素密度进行缩放过的了。换言之一张放在mdpi文件夹中的图片在mdpi的手机和xhdpi的手机上获取的IntrinsicWidth大小比是1:2(因为获得的是像素数嘛)。


2 Drawable的子类们

Drawable的子类有很多,BitmapDrawable,ScaleDrawable,StateListDrawable等等,这些Drawable既可以在代码中直接使用,也可以通过他们对应的XML标签定义Drawable文件的方式来使用。这些标签单独使用功能还稍显乏力,但是由于有很多是可以互相嵌套的,所以最终也可以形成很复杂很有用的效果。
具体每个标签有什么属性,怎么使用就不提了。这里有一个网页,其中标签的使用方式和嵌套结构看起来一目了然。
http://idunnolol.com/android/drawables.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值