在原生 Android 开发中,许多控件默认都是方方正正的,而我个人也比较喜欢这种设计,因为 Google 的 Material Design 就是从纸片中提炼出来的。
但是近年来 Material Design 的发展,似乎更加往大圆角的方向靠拢了。
Android 的原生控件中是不支持直接设置类似 Radius 的属性,所以又得另辟蹊径了。
Shape Attr
可以通过一个 XML 资源文件来定义,属性参考如下:
shape (形状)
最外层标签,用于定义控件的形状。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:dither="false"
android:innerRadius="16dp"
android:innerRadiusRatio="8"
android:thickness="8dp"
android:thicknessRatio="8"
android:tint="@color/colorAccent"
android:tintMode="add"
android:useLevel="false">
...
</shape>
属性比较多,听我一一道来。
android:shape
是控件的形状,默认为矩形 rectangle
,其他可选值还有椭圆 oval
、线 line
和 环 ring
。
android:dither
用于指定在位图的像素配置与屏幕不同时(例如:ARGB_8888 位图和 RGB_565 屏幕)是否启用位图的抖动,默认值 true
,当值为 false
时则停用抖动。
android:innerRadius
是内环半径;android:innerRadius
是内环厚度比,即环的宽度比表示内环半径,默认为 3
,可被 android:innerRadius
的值覆盖。android:thickness
是环的厚度,android:thicknessRatio
是环的厚度比,即环的宽度比表示环的厚度,默认为 9
,可被 android:thicknessRatio
的值覆盖。这四个属性只有当形状为 ring
的时候才有效。
android:tint
用于着色,这个我们在其他控件也有用到。
android:tintMode
是着色类型,有 add
、multiply
、screen
、src_atop
、src_in
和 src_over
六个可选值,这里不细说。
android:useLevel
这个属性比较特殊,是个布尔类型,默认值为 false
,一般情况下不需要修改它,为 true
时可在 LevelListDrawable
使用。
corners (圆角)
Creates rounded corners for the shape. Applies only when the shape is a rectangle.
用于定义控件的圆角属性,仅可用于矩形 Shape。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:radius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp"
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp" />
</shape>
这个比较简单,不过多解释。
solid (填充)
A solid color to fill the shape.
用于定义控件的填充颜色。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorAccent" />
</shape>
有且仅有颜色这一属性。
gradient (渐变)
Specifies a gradient color for the shape.
用于定义控件的渐变色及渐变样式等。
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:type="radial"
android:angle="90"
android:startColor="@color/colorPrimaryDark"
android:centerColor="@color/colorAccent"
android:endColor="@color/colorPrimary"
android:centerX="50%"
android:centerY="50%"
android:gradientRadius="8dp"
android:useLevel="false" />
</shape>
这个相对比较复杂,分组来说。
android:type
是渐变的样式,有三个可选值,线性渐变 linear
是默认值,另外还有放射渐变 radial
和扫描渐变 sweep
。
android:angle
是渐变角度,须为 45 的整倍数,其中 0 为从左到右,90 为从上到下。
android:startColor
、android:centerColor
和 android:endColor
分别是渐变的起始点、中间点和结束点颜色,但你可以按需设置,因为其支持两色渐变和三色渐变,即当选择两色渐变时,android:centerColor
可以不用填写。
android:centerX
和 android:centerY
是渐变中心点 X 和 Y 的相对位置,取值范围为 0~1。
android:gradientRadius
是渐变的半径,只有当渐变类型为 radial
时才有效。
android:useLevel
这个属性比较特殊,是个布尔类型,默认值为 false
,一般情况下不需要修改它,而使用 LevelListDrawable
时就要设置其为 true
。
stroke (描边)
A stroke line for the shape.
用于定义控件的描边属性。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="8dp"
android:color="@color/colorAccent"
android:dashWidth="8dp"
android:dashGap="8dp" />
</shape>
android:width
是描边的宽度。android:color
是描边的颜色。
一般情况下描边为实线,如果想设置虚线,则需要另外两个属性,android:dashWidth
是指虚线段的长度,android:dashGap
是指虚线段间隔的长度。
padding (边距)
Padding to apply to the containing View element (this pads the position of the View content, not the shape).
用于定义控件的边距属性。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<padding
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp" />
</shape>
这个也比较简单,不过多解释。
size (大小)
The size of the shape.
用于定义控件的尺寸属性。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size
android:width="128dp"
android:height="128dp" />
</shape>
同样比较简单,不过多解释。
Usage
用法也不复杂,在「drawable」文件夹中新建一个 XML 资源文件,将上面的属性按照需要进行组合即可。
比如,我建一个「button_shape.xml」,用来定义 Button
控件的形状。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorAccent" />
<corners
android:topLeftRadius="5dp"
android:topRightRadius="10dp"
android:bottomLeftRadius="15dp"
android:bottomRightRadius="0dp" />
</shape>
代码并不难理解,形状为矩形,颜色设定为主题色,为四个圆角半径设定为 不同的值。
然后使用其在控件属性中设置为 android:background
:
<Button
android:layout_width="128dp"
android:layout_height="wrap_content"
android:background="@drawable/button_shape"
android:text="Button" />
效果如下:
其实 Shape 的可配置属性并没有很复杂,所以学起来也不会很难上手,但是却足够我们使用。