前言:
关于Drawable的学习.主要的学习来源是开发艺术探索这本书,关于Drawable的其他知识本人未在网上看其他的,这本书上已经讲的非常详细了.都是非常基础的知识.没有什么难点.这里主要是从一个初中级程序猿的角度,和大家一起分享学习的知识.那么今天的学习就开始了.让我们来一边学习一边验证吧.
Drawable的简介
Drawable表示的是一种可以在Canvas上进行绘制的抽象的概念,它的种类有很多,最常见的颜色和图片都可以是一个Drawable.
这里的Drawable指是的下面这个
而不是这个
题外话:关于Drawable的微技巧郭神有篇文章写的很好,可以去看看Android drawable微技巧,你所不知道的drawable的那些细节
我们继续.
Drawable的内部宽/高参数
获取Drawable的宽,返回结果为int值
public int getIntrinsicWidth(){}
获取Drawable的高,返回结果为int值
public int getIntrinsicHeight(){}
但是注意了啊.这个Drawable的宽高还是有很多门道道的.不是所有的Drawable都有宽高的.
一个图片形成的Drawable的宽高就是图片宽高,颜色所形成的的Drawable没有内部宽高的概念.当被用作View的背景时,Drawable会被拉伸至View的同等大小.我们来验证一下.
布局就只是一个宽100dp,高150dp的button,没有任何额外的属性.看一下的pop_bg的代码,也很简单
<Button
android:id="@+id/button"
android:layout_below="@+id/buttonPanel"
android:layout_width="100dp"
android:layout_height="150dp"
android:background="@drawable/pop_bg"/>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<solid android:color="#00000000"/>
</shape>
代码部分
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Drawable drawable = getDrawable(R.drawable.pop_bg);
if (drawable != null) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Log.i("没有padding的drawable宽", width + "");
Log.i("没有padding的drawable高", height + "");
int bt_width = button.getMeasuredWidth();
int bt_height = button.getMeasuredHeight();
Log.i("没有padding的按钮宽", bt_width + "");
Log.i("没有padding的按钮高", bt_height + "");
}
}
});
输出打印:
01-13 16:09:22.821 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable宽: -1
01-13 16:09:22.821 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable高: -1
01-13 16:09:22.822 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮宽: 300
01-13 16:09:22.822 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮高: 450
可以看出:button是有宽高的,但的Drawable获取到的宽高都是-1.也就是没有内部宽高.那我们来完善一下上述的结论:
当作为一个View的背景时,如果drawable是由颜色形成的,那么drawable仍然没有宽高.
那么它什么时候可以获取到宽高呢?我们来试一试.
把pop里的代码修改下.代码如下
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/checkbox_normal"/>
修改为图片
输出结果如下
01-13 16:52:07.106 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable宽: 96
01-13 16:52:07.106 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable高: 99
01-13 16:52:07.106 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮宽: 300
01-13 16:52:07.106 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮高: 450
看到结果证明可以获取到宽高了,这个宽高也正是图片的宽高.这里虽然button的宽高为300/450,但是对于drawable的宽高是没有影响的.影响drawable宽高大小的是图片本身的宽高.
那么看到这里我们其实已经明白,Drawable本身并没有大小的概念,完全取决于其形成因素.(有什么卵用,从来没获取过)
常见的Drawable分类
Android内置了很多种Drawable,做了这么长时间的开发,用到的也就两三个.所以我们以用的最多的ShapeDrawable,LayerDrawable,StateListDrawable,以及自定义Drawable.这里只介绍需要介绍的属性,一看就知道是什么意思的就不说了.
*一.ShapeDrawable*
对应的标签为: 其实体类实际上是GradientDrawable.各个属性的含义.这里给出所有的属性
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle|oval|line|ring">
<corners
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer"
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer" />
<gradient
android:angle="integer"
android:centerColor="color"
android:centerX="integer"
android:centerY="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type="linear|radial|sweep"
android:useLevel="true|false" />
<padding
android:bottom="integer"
android:left="integer"
android:right="integer"
android:top="integer" />
<size
android:width="integer"
android:height="integer" />
<solid android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashGap="integer"
android:dashWidth="integer" />
</shape>
(1).shape标签本身的属性
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle|oval|line|ring"
/>
只有一条选择图形的属性 从左到右分别为矩形|椭圆|线|圆环
默认值为rectangle(矩形).其中ring圆环比较怪异.试验了几次.看了很多博客,几乎没有人用这个属性.这里就不列出来了.有兴趣的可以自行查阅.
(2). corners标签
表示shape四个角的角度.只适用于矩形shape.
这里的角度是指圆角的程度,用px来表示,有如下5个属性.
<corners
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer"
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer" />
每个属性的名字已经告诉我们是什么意思了,这里就不过多赘述.
值得一提的是这里的角度指的是圆角的程度,用px来表示. 所有属性同时存在时,radius的优先级最低,会被其他四个属性覆盖.也就是说其他四个属性谁存在,就会覆盖radius中对应角的数值.
(3).gradient标签
表示渐变效果和下面要介绍的互相排斥,只能存在一个.
<gradient
android:angle="integer"
android:centerColor="color"
android:centerX="integer"
android:centerY="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type="linear|radial|sweep"
android:useLevel="true|false" />
android:angle
渐变的角度.默认为0,其值必须为45的倍数,0表示从左到右渐变,90表示从下到上. 请看下图(猿行天下的博客)
android:type=”linear|radial|sweep”
渐变的类型,从左到右分别为线性渐变,径向渐变,扫描性渐变.默认值为线性渐变.
android:gradientRadius=”integer”
渐变半径,仅当android:type=”radial”(径向渐变)时有效.
android:useLevel=”true|false”
一般为false,也建议为false.想了解的可以去了解,没什么用.
(4).padding标签
<padding
android:bottom="integer"
android:left="integer"
android:right="integer"
android:top="integer" />
padding属性就不介绍了.一看便知
(5).solid和stroke标签
<solid android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashGap="integer"
android:dashWidth="integer" />
solid这个标签标示纯色填充,也就是通过它形成的Drawable获取不到宽高.通过android:color即可指定shape中填充的颜色
stroke
android:dashGap=”integer” 组成虚线之间的间隔,间隔越大,虚线之间的空隙越大.
android:dashWidth=”integer” 组成虚线的线段的宽度.
二者任何一个为0,那么虚线效果将不能生效.
(6).size标签
分别表示shape的固有宽高,但是一般来说它并不是shape最终显示的大小.
这里直接放出总结:对于shape来说,默认情况下是没有固定宽高这个概念的,标签指定宽高信息之后,那么这个shape就有了所谓的固定宽高,但是作为View背景时,shape还是会被拉伸或者缩小为View的大小.
那么这个size什么时候有效呢?我的理解是当shape的组成仅仅是由颜色也就是和组成,同时view的宽高设置为wrap_content时,此时View的宽高即为这个size设置的宽高.(尼玛完全没用啊,浪费感情).我们来验证下.
同样是最顶部的代码,修改一下button和pop
<Button
android:id="@+id/button"
android:layout_below="@+id/buttonPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/pop"/>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="100dp"
android:height="150dp" />
<solid android:color="color" />
</shape>
输出结果:
01-13 16:09:22.821 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable宽: -1
01-13 16:09:22.821 15129-15129/com.example.wyfsh.myapplication I/没有padding的drawable高: -1
01-13 16:09:22.822 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮宽: 300
01-13 16:09:22.822 15129-15129/com.example.wyfsh.myapplication I/没有padding的按钮高: 450
输出结果
看,我们控件设置wrap_content,但是获取到的宽高和我们在布局里设置有同样的效果,但是仅仅是局限于颜色形成的drawable.图片因为本身有固定的宽高,所以肯定会被改变的.
本来还想接着写,有点太长了,放到下一个吧.主要是说明LayerDrawable,StateListDrawable,以及自定义Drawable.
*这里对于我的写博客的初衷再次说明.最重要的是督促自己的学习,同时分享给大家我的学习历程和学到的知识,我会尽量从我(一个初中级之间徘徊的程序员)的角度去学习,同时分享学习中遇到的问题,分享我在学习一个知识时的想法.因为我相信我勉强可以作为Android程序员中占比最大的群体的一个典型的缩影==>.仅仅是能做项目,如何做的更好,让自己有更高的技术水平,每天面对海量的知识不知道怎么办.对于高阶的知识一知半解,看了又忘.
我身边这样的人数不胜数,也是在大浪淘沙的形式下苦苦挣扎的苦逼码农.可是总要向前的.那么就一点一点的进步好了*