使用XML实现悬浮的添加按钮

使用XML实现悬浮的添加按钮

  • 不过于依赖过高版本
  • 尽量简单易用

1,使用自定义的ImageButton来实现。一个圆加上加号,可以用LayerDrawable

2,按下时,四周出现了半透明的灰色边框。看起来本身背景的颜色也变深了,可以考虑属性动画或者selector(也可以自定义StateListDrawable),或者直接在Ondraw中绘制即可。

3,如何保证其在整个页面上方,并且不影响其他控件。
首先想到的就是FrameLayout

开动

先来把按钮做出来,效果是一个圆,一个加号。GradientDrawable来做圆,PNG的加号,然后通过LayerDrawable组合。
对于GradientDrawable 的使用可以参考Android 文档的Drawable Resources章节,添加

http://wiki.eoeandroid.com/Drawable

节选如下

Shape 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攒的)

layout

<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>

buttonselector.xml


<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>

addbutton.xml


<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>

pressbutton.xml


<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>

circle.xml


<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>

circlebound.xml


<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>

#

效果图(原谅我找的渣素材,电脑不能使用PS等软件):

使用XML实现悬浮的添加按钮_第1张图片

后记:
写完发现其实把整个效果做成一个自定义的View是更好地,首先展开XML浪费很多时间。其次这么组合实际上比较复杂,并且Layer图像还有其自己的限制。
如果做成View。只需要在onDraw里面绘制即可。
并且可以增加比如加号旋转的属性,可以方便的做成属性动画,在后面需要让里面的加号旋转时直接创建一个属性动画即可。

你可能感兴趣的:(Android应用)