0%

Android Ripple(波纹效果)

控件中的Ripple标签,即对应一个RippleDrawable,当它被设置为一个控件的background属性时,控件在按下时,即会显示水波效果

自定义

没有边界的Ripple(Ripple With No Mask)

波纹的内直径就是控件的长或者宽,实现内容如下,不需要任何操作即可。

1
2
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight" />

有边界的Ripple(Ripple With Mask)

波纹不超过控件的显示范围,实现内容如下,需要增加一个@android:id/mask配置,配置中的颜色就是波纹的背景色,会与ripple颜色重叠显示。

1
2
3
4
5
6
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:id="@android:id/mask">
<color android:color="@color/white" />
</item>
</ripple>

用图片作边界的Ripple(Ripple With Picture Mask)

波纹不超过图片的显示范围,实现内容如下,需要增加一个@android:id/mask配置,配置中的图片就是波纹的背景,会与ripple颜色重叠显示。

1
2
3
4
5
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:id="@android:id/mask" android:drawable="@drawable/icon">
</item>
</ripple>

用形状作边界的Ripple(Ripple With Shape Mask)

波纹不超过形状的显示范围,实现内容如下,需要增加一个@android:id/mask配置,配置中的形状就是波纹的背景,会与ripple颜色重叠显示。

  • shape.xml
    1
    2
    3
    4
    5
    6
    <shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <solid android:color="#ff9d77"/>
    <corners
    android:bottomRightRadius="100dp"/>
    </shape>
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#FF0000" >
    <item
    android:id="@android:id/mask"
    android:drawable="@drawable/shape"/>
    </ripple>

搭配selector作为Ripple(Ripple With Selector)

如果在一个ripple标签中,添加一个item,在item的内部写上标签,那么这个RippleDrawable在按下的时候,同时具有水波效果和selector指定的图层。

波纹不超过Selector的显示范围,实现内容如下,需要增加一个@android:id/mask配置,配置中的Selector就是波纹的背景,会与ripple颜色重叠显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#FF0000" >
<item>
<selector>
<item
android:drawable="@drawable/icon_p"
android:state_pressed="true">
</item>
<item
android:drawable="@drawable/icon_n"
android:state_pressed="false">
</item>
</selector>
</item>
</ripple>

系统默认

在控件中设置背景如下:

  • 有边界:
    1
    2
    3
    <ImageView
    android:background="?selectableItemBackground"
    />
  • 无边界:
    1
    2
    3
    <ImageView
    android:background="?selectableItemBackgroundBorderless"
    />

selectableItemBackground

文件位于:
/sdk/android/platforms/android-29/data/res/drawable/item_background_material.xml

文件内容如下:

1
2
3
4
5
6
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item android:id="@id/mask">
<color android:color="@color/white" />
</item>
</ripple>

文件中的mask参数,用来控制波纹动画的背景或者说是边界,这里波纹动画只会在mask中显示,也就达到动画不超过控件的目的。

selectableItemBackgroundBorderless

文件位于:
/sdk/android/platforms/android-29/data/res/drawable/item_background_borderless_material.xml
文件内容如下:

1
2
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight" />

文件中的没有mask参数,波纹动画效果会超过控件的大小。

colorControlHighlight(?attr/colorControlHighlight)

文件位于:
/sdk/android/platforms/android-29/data/res/color/ripple_material_light.xml这里的light与Theme.AppCompat.Light有关。
文件内容如下:

1
2
3
4
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="@dimen/highlight_alpha_material_light"
android:color="@color/foreground_material_light" />
</selector>

参考

where-can-i-found-definition-for-selectableitembackgroundborderless-reference-at