Android Drawable系列
日常开发中,一些简单的背景或者图形都会使用xml的shape标签完成,经常使用在按钮的背景上。
shape的优点还是很多的
文件比切图小
节约内存
支持拉伸
shape的属性虽然比较简单,但是也能绘制出一些比较复杂的形状
概览
首先来看看shape标签所支持的标签以及属性,如下图:
Shape
左侧是shape标签的自身属性,右侧是shape标签所支持的标签和标签的属性。
下面是一份xml属性实例和说明
android:dither=["true" | "false"] //将在位图的像素配置与屏幕不同时(例如:ARGB 8888 位图和 RGB 565 屏幕)启用位图的抖动;值为“false”时则停用抖动。默认值为 true。
android:shape=["rectangle" | "oval" | "line" | "ring"]//分别为矩形、椭圆、线、环。默认为矩形rectangle
android:innerRadius="integer" // shape为ring时有效,内环半径
android:innerRadiusRatio="float" // shape为ring时有效,内环的厚度比,即环的图形宽度与内环半径的比例,按照这个比例计算内环半径,默认为3,可被innerRadius值覆盖
android:thickness="integer" // shape为ring时有效,环的厚度
android:thicknessRatio="float" // shape为ring时有效,环的厚度比,即环的图形宽度与环的厚度的比例,按照这个比例计算环的厚度,默认为9,可被thickness值覆盖
android:tint="color" // 给shape着色
android:tintMode=["src_in" | "src_atop" | "src_over" | "add" | "multiply" | "screen"] // 着色类型
android:useLevel=["true" | "false"] // 较少用,一般设为false,否则图形不显示。为true时可在LevelListDrawable使用
android:visible=["true" | "false"] >
android:radius="integer" // 圆角半径,设置下面四个属性时,对应的位置属性会被覆盖
android:topLeftRadius="integer" // 左上角圆角半径
android:topRightRadius="integer" // 右上角圆角半径
android:bottomLeftRadius="integer" // 左下角圆角半径
android:bottomRightRadius="integer" // 右下角圆角半径
/>
android:type=["linear" | "radial" | "sweep"]// 渐变类型,线性、放射性、扫描性;默认为线性
android:angle="integer" // 渐变角度,渐变类型为linear时有效;默认为0,从左至右渐变,角度逆时针方向计算,角度需要时45的整数倍数
android:centerColor="integer" // 渐变中间位置颜色
android:startColor="color" // 渐变开始位置颜色
android:endColor="color" // 渐变结束位置颜色
android:centerX="float" // 设置渐变中心的X坐标,取值区间[0,1],默认为0.5,即中心位置
android:centerY="float" // 设置渐变中心的Y坐标,取值区间[0,1],默认为0.5,即中心位置
android:gradientRadius="integer" // type为放射性渐变radial时有效,渐变的半径
android:useLevel=["true" | "false"] // 与shape中该属性的一致
/>
android:left="integer" // 左边距
android:top="integer" // 上边距
android:right="integer" // 右边距
android:bottom="integer" // 下边距
/>
android:width="integer" // 图形宽度
android:height="integer" // 图形高度
/>
android:color="color" // 图形的填充色
/>
android:width="integer" // 描边的宽度
android:color="color" // 描边的颜色
android:dashWidth="integer" // 虚线宽度
android:dashGap="integer" // 虚线间隔
/>
因为shape中的属性更的是组合使用,所以举例没法单独只使用一个标签。
solid、corners和stroke
经常使用的就是solid、corners、stroke这三个标签
下面是这个Button背景的xml代码
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
android:width="3dp"
android:color="#D81B60"
android:dashWidth="10dp"
android:dashGap="5dp"/>
solid就是整个区域的填充色
corners则是控制了背景的4个角的圆角半径
stroke控制了描边的属性,color表示线的颜色;width描边的宽度,其实就是图中红线的高度;dashWidth表示虚线中红线的宽度;dashGap表示虚线间隔宽度,也就是红色之间的间隔距离
corners属性覆盖
再来看看corners标签的属性覆盖规则。下图中将radius属性设置为10dp,并同时设置给其他的四个属性不同的值,从图中可以看出四个属性将都radius属性覆盖了。
具体的xml代码:
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
android:bottomLeftRadius="30dp"
android:bottomRightRadius="40dp"
android:radius="10dp"
android:topLeftRadius="0dp"
android:topRightRadius="20dp"/>
padding
再来看看padding标签的作用,图片如下:
第一行的TextView的背景没有设置padding属性;第二行则是使用了padding标签,不低的地方在于有无内容的差别。shape的xml代码如下:
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp"/>
shape中虽然使用了padding标签,但是在被设置该背景的view上依然可以通过修改paddingLeft等对应的相关属性进行覆盖。
size
size控制图形的宽高尺寸,对应属性也就android:width和android:height
但是,在作为背景的情况下,shape的size属性并不是完全有效的,最后的显示效果还是会由view来决定,size只是在view的宽(或高)为wrap_content且显示内容后的实际大小不超过size所设置的值得时候才会生效。这个效果其实比较类似minWidth
和minHeight两个属性的效果。
下图中,左边的内容没有超出,按照size所设置的大小显示,而右边的内容超出了size所设置的大小,按照实际大小显示。这里比较简单,不上代码了。
不要这样就觉得size没有什么作用,例如下图
截图的原因,图片被放大了,这些圆使用ImageView的src显示时,ImageView只需要设置wrap_content就可以按照设置的大小显示了。
当然,如果你修改了ImageView的大小,那shape的显示就会根据ImageView的scaleType来决定最后的显示效果了。
gradient
不太清楚gradient标签的使用频率,毕竟是UI效果,实际工作中涉及到渐变的时候基本都是设计小姐姐直接给图的。不过不妨碍我们了解gradient的用法。
android:type
这里先说android:type属性,表示渐变类型,有三个可以选择的属性linear线性、radial放射性、sweep扫描性,默认为线性
下图,从左到右的中android:type分别是linear线性、radial放射性、sweep扫描性
线性:比较好理解,就是一条线从左到右,准确的说是从一边到另一边渐变,而这个方向是可以调整的,后面会说明
放射性:从一个中心点向外渐变
扫描性:这个比较像雷达,具体看图,我描述不出来,不过也是有中心点的
渐变颜色
先以默认渐变类型来看下主要的三个属性:
android:centerColor 渐变中间位置的颜色
android:endColor 渐变结束位置的颜色
android:startColor 渐变开始位置的颜色
上图中第一个按钮,设置了开始颜色是红的,中间颜色是白色,结束颜色是绿的,具体代码如下:
android:centerColor="#FFFFFF"
android:startColor="#D81B60"
android:endColor="#008577"/>
android:angle
start -> end默认的方向是从左到右,通过设置android:angle属性可以修改这个方向,0 -> 360 增加时,方向是逆时针调整的。上图中,第2、3、4个按钮的shape的android:angle属性值分别是90、180、270。注意,android:angle属性需要时45的整数倍。
android:centerX和android:centerY
这两个属性是控制渐变中心位置的坐标的,取值区间[0,1],默认为0.5
上图中,三种渐变类型都设置了中心点的位置,radial和sweep两种类型比较好理解,就是控制中心在图形中的的相对位置。
linear类型也会受到这两个属性的改变,因为是线性所以作用应该是对线的中心点的控制,我试了一下,centerX或者centerY都能控制渐变的中心点,而且不受android:angle属性影响。但是centerX和centerY同时使用时,不存在属性前后顺序而导致属性覆盖的的情况,只有centerX起作用。
android:gradientRadius
设置渐变的半径,当type为放射性渐变radial时有效,差异效果如下图:
当solid和gradient同时使用时,在代码中比较靠下的标签会覆盖之前的标签属性
shape
shape的标签属性都了解完了,接着就是shape自身的属性了
前面举例的都是矩形,也就是android:shape="rectangle"的情况下,接下来看看其他三种类型,
首先是line,因为虚线和实线相差两个属性,就直接用虚线举例了
下面是具体的xml代码:
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
android:width="3dp"
android:color="#D81B60"
android:dashWidth="10dp"
android:dashGap="5dp"/>
经过查资料和一些测试,使用line类型有些限制
必须使用stroke标签,view显示的高度必须大于(必须是大于,等于都不行)stroke标签中width宽度属性的值。也就是说,view所设置的高度需要大于虚线高度;如果使用了size标签,size的height也必须比大于虚线高度
4.0 以上手机,默认使用硬解码,虚线在真机会显示成实线,可以关闭页面的硬件加速,也可以给相关的view设置成软解layerType="software"
再来是oval,虽然表示的是椭圆,其实只需要显示图形的view是正方形就可以显示成圆了。之前在使用size就是以圆为例子举例的,在ImageView的src中使用shape,xml代码如下:
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
android:height="20dp"/>
当然,也可以通过限制view的宽高,来保证显示圆。
oval和rectangle在使用其他的属性方面规则基本一直,只是corners标签不在具有任何效果。
最后是ring,关于ring的属性比其他的三种图形要多出4个属性
innerRadius,shape为ring时有效,内环半径
innerRadiusRatio,shape为ring时有效,内环的厚度比,即环的图形宽度与内环半径的比例,按照这个比例计算内环半径,默认为3,可被innerRadius值覆盖
thickness,shape为ring时有效,环的厚度
thicknessRatio,shape为ring时有效,环的厚度比,即环的图形宽度与环的厚度的比例,按照这个比例计算环的厚度,默认为9,可被thickness值覆盖
上图中第一个环的xml代码如下:
xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="false"
android:shape="ring">
android:height="100dp"/>
可以看到并没有设置什么其他的属性,只是设置了solid和size,这基本就是默认的一个环了,内环半径和环的厚度都是分别是按3和9的比例计算的,后面会具体讲解这两个值得意思。
第二个环,则是添加android:thickness="5dp"属性,设置了环的厚度为5dp
第三个环,则是添加android:innerRadius="10dp"属性,设置内环半径为10dp
第四个环,可以算解释了innerRadiusRatio和thicknessRatio两个属性,具体xml代码如下:
xmlns:android="http://schemas.android.com/apk/res/android"
android:useLevel="false"
android:innerRadiusRatio="3"
android:thicknessRatio="100"
android:shape="ring">
innerRadiusRatio和thicknessRatio两个属性都是对比view最终显示的大小来计算的,可以对应着两个公式:
innerRadius = view.width / innerRadiusRatio
thickness = view.width / thicknessRatio
这样以来着两个属性就比较好理解了
对于ring的使用还有几点需要注意:
必须写useLevel="false",否则不显示
如果android:thickness和android:innerRadius设置了值,无论view的大小如何设置,将不会影响图片大小,这有可能会导致图形显示不全。
padding和corners两个标签不起作用,其他的标签可以正常的使用
PS:好了,shape的基本属性算是了解完了,如有不正确的地方,还请大佬指正。
如果喜欢该文章,可以扫码领个红包支持一下
图片发自简书App