1,使用自定义的ImageButton来实现。一个圆加上加号,可以用LayerDrawable
2,按下时,四周出现了半透明的灰色边框。看起来本身背景的颜色也变深了,可以考虑属性动画或者selector(也可以自定义StateListDrawable),或者直接在Ondraw中绘制即可。
3,如何保证其在整个页面上方,并且不影响其他控件。
首先想到的就是FrameLayout
先来把按钮做出来,效果是一个圆,一个加号。GradientDrawable来做圆,PNG的加号,然后通过LayerDrawable组合。
对于GradientDrawable 的使用可以参考Android 文档的Drawable Resources章节,添加
http://wiki.eoeandroid.com/Drawable
这是一个定义在XML中的通用形状。
res/drawable/filename.xml
文件名作为资源ID。
指向一个渐变Drawable的资源指针。
Java: R.drawable.filename
XML: @[package:]drawable/filename
语法:
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
shape>
形状drawable,必须是根元素。
xmlns:android
字符型,必要的,定义XML的命名空间,必须是”http://schemas.android.com/apk/res/android“。
android:shape
关键字,定义形状的类型,取值是:
取值 | 描述 |
---|---|
“rectangle” | 填充包含的视图的矩形,是默认形状。 |
“oval” | 椭圆形,适合包含的视图的尺寸。 |
“line” | 划分包含的视图的水平线,这个形状要求元素来定义线的宽度。 |
“ring” | 环形。 |
如下属性只有当android:shape=”ring”时才使用。
android:innerRadius
尺寸,内环半径(中间的孔),作为一个尺寸值或尺寸资源。
android:thickness
尺寸,环的厚度,作为一个尺寸值或尺寸资源。
android:thicknessRatio
浮点型,环的厚度比上环的宽度,例如,如果android:thicknessRatio="2",厚度等于环的宽度的1/2,此值被android:innerRadius重写,默认为3.
android:useLevel
布尔型,为"true"时,用于LevelListDrawable,正常情况设为"false",或者形状不出现。
为形状创建圆角,只有当形状为矩形时才应用。
属性:
android:radius
尺寸数,所有的角的半径,作为一个尺寸值或尺寸资源,对于每个角会重写如下的属性:
android:topLeftRadius
尺寸数,左上角的半径,作为一个尺寸度值或尺寸资源。
android:topRightRadius
尺寸数,右上角的半径,作为一个尺寸度值或尺寸资源。
android:bottomLeftRadius
尺寸数,左下角的半径,作为一个尺寸值或尺寸度资源。
android:bottomRightRadius
尺寸数,右下角的半径,作为一个尺寸值或尺寸度资源。
注意:每个角的角半径必须大于1,不然没有圆角。如果想指定所有的角都不是圆角,使用android:radius 来设定默认的角半径大于1,然后重写每个角,并指定每个角的半径值为所需要的值,如果不需要圆角,值为0(0dp)。
为形状指定渐变颜色。
属性:
android:angle
整形,渐变的角度,度数,0度为从左到右,90度是从底到上,必须是45度的倍数,默认为0.
android:centerX
浮点型,距离渐变中心的X坐标的相对位置(0 - 1.0)。
android:centerY
浮点型,距离渐变中心的Y坐标的相对位置(0 - 1.0)。
android:centerColor
颜色,可选择开始到结束之间的颜色,作为一个十六进制值或颜色资源。
android:endColor
颜色,结束颜色,作为一个十六进制值或颜色资源。
android:gradientRadius
浮点型,渐变的半径,只有当android:type="radial"才使用
android:startColor
颜色,开始颜色,作为一个十六进制值或者颜色资源。
android:type
关键字,使用的渐变模式,有效值如下:
取值 | 描述 |
---|---|
linear | 线性渐变,默认选择 |
radial | 辐射渐变,开始颜色也是结束颜色 |
sweep | 卷曲线渐变 |
android:useLevel布尔型,为”true”时,作为一个 LevelListDrawable。
<padding>
填充以适用于视图元素(填充视图内容的位置而不是形状。
属性:
android:left
尺寸,左边填充,作为一个尺寸值或者尺寸资源。
android:top
尺寸,顶上填充,作为一个尺寸值或者尺寸资源。
android:right
尺寸,右边填充,作为一个尺寸值或者尺寸资源。
android:bottom
尺寸,底边填充,作为一个尺寸值或者尺寸资源。
形状的大小。
属性:
android:height
尺寸,形状的高,作为一个尺寸值或者尺寸资源。
android:width
尺寸,形状的宽,作为一个尺寸值或者尺寸资源。
注意:形状缩放大小以适应视图,与定义的尺寸相称,默认,当在一个图像视图使用形状时,可以限制缩放,通过设置 android:scaleType to "center"。
固定颜色填充形状。
属性:
android:color
颜色,用到形状上的颜色,作为一个十六进制值或颜色资源。
形状的笔触。
属性:
android:width
尺寸,线的宽度,作为一个尺寸值或尺寸资源。
android:color
颜色,线的颜色,作为一个十六进制值或者颜色资源。
android:dashGap
尺寸,虚线间隔,作为一个尺寸值或尺寸资源,只有当设置android:dashWidth才有效。
android:dashWidth
尺寸,每个虚线的大小,作为一个尺寸值或尺寸资源,只有当设置android:dashGap才有效。
例子:
XML文件存于res/drawable/gradient_box.xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#FFFF0000"
android:endColor="#80FF00FF"
android:angle="45"/>
<padding android:left="7dp"
android:top="7dp"
android:right="7dp"
android:bottom="7dp" />
<corners android:radius="8dp" />
shape>
把此XML布局应用到一个视图的形状drawable:
<TextView
android:background="@drawable/gradient_box"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
应用程序代码获得形状drawable,应用到视图:
Resources res = getResources();
Drawable shape = res. getDrawable(R.drawable.gradient_box);
TextView tv = (TextView)findViewByID(R.id.textview);
tv.setBackground(shape);
对于我们想要的一个圆形和加号,圆形用shape做,加号最初想也用shape做,然后组合为一个LayerDrawable,但是会有一个自动缩放的问题。
注意:
对于LayerDrawable默认情况下所有绘制项目缩放,以适应包含视图的大小。因此,放置图像在图层列表的不同位置,可能会增加View的大小和一些图像需要扩展到合适的大小。为了避免列表中的扩展项,在元素内使用元素,指定可绘制性和定义gravity为不会扩展的属性,诸如“居中”。例如,下面的定义了一个项,扩展到适应其容器View的大小:
<item android:drawable="@drawable/image" />
为避免扩展,如下的例子使用一个 元素,gravity属性为居中:
<item>
<bitmap android:src="@drawable/image"
android:gravity="center" />
item>
也没找到更好地办法阻止shape的放大,只能旋转PNG图片的Drawable来做加号
然后还需要按下和抬起时候的不同显示效果,可以使用StateListDrawable,在XML文件中则是selector 来定义。
(基本没有用java代码,全部用XML攒的)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
ListView>
<ImageButton
android:id="@+id/imagebutton"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:background="@drawable/buttonselector"
android:contentDescription="@string/hello_world" />
FrameLayout>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
<item android:drawable="@drawable/pressbutton" android:state_pressed="true">item>
<item android:drawable="@drawable/addbutton">item>
selector>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/bg"
android:drawable="@drawable/circle">
item>
<item
android:id="@+id/add"
android:drawable="@drawable/add2">
item>
layer-list>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/bound"
android:drawable="@drawable/circlebound">
item>
<item
android:id="@+id/add"
android:drawable="@drawable/add2">
item>
layer-list>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false"
android:visible="true" >
<solid android:color="@color/blue" />
<stroke
android:width="6dp"
android:color="@color/transparent" />
<size
android:height="40dp"
android:width="40dp" />
shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false"
android:visible="true" >
<solid android:color="@color/blue" />
<stroke
android:width="3dp"
android:color="@color/gray" />
<size
android:height="45dp"
android:width="45dp" />
shape>
后记:
写完发现其实把整个效果做成一个自定义的View是更好地,首先展开XML浪费很多时间。其次这么组合实际上比较复杂,并且Layer图像还有其自己的限制。
如果做成View。只需要在onDraw里面绘制即可。
并且可以增加比如加号旋转的属性,可以方便的做成属性动画,在后面需要让里面的加号旋转时直接创建一个属性动画即可。