Android动画之触摸反馈动画
Material Design中的触摸反馈在用户和UI元素交互的点提供瞬时视觉确认。例如,当按钮被触摸时显示一个水波纹效果。 这是 Android 5.0 默认的触摸反馈动画。
水波纹动画通过新的 RippleDrawable 类实现。
水波纹效果可以配置在 View 边界的末端或超出 View 的边界。
使用系统自带的两个 Ripple 波纹效果
//有边界
?android:attr/selectableItemBackground
//无边界 (要求API21以上)
?android:attr/selectableItemBackgroundBorderless
使用时只需要把上面这两个值作为 View 的 android:background="" 或 android:foreground="" 即可(如果已经有背景, 可以设置到前景属性中)。
想要效果显示出来要保证 View 的 android:clickable="true" 。
这里的颜色是系统默认的,可以在 theme 里更改默认的波纹颜色:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- API 21 theme customizations can go here. -->
<item name="android:colorControlHighlight">#ff0000</item>
</style>
也可以通过代码设置
int[] attrs = new int[]{R.attr.selectableItemBackground};
TypedArray typedArray = getActivity().obtainStyledAttributes(attrs);
int backgroundResource = typedArray.getResourceId(0, 0);
mView.setBackgroundResource(backgroundResource);
自定义 Ripple
无边界
ripple 说是触摸反馈动画,其实它就是一个 Drawable,所以定义时需要放到 drawable 文件夹下:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#4285f4">
</ripple>
- 上面中 ripple 属性中 color 代表的是波纹的颜色。
- ripple 中还有一个属性为 radius (波纹大小),则触摸显示的波纹为设置的固定大小,不会为手指触摸点开始显示。
- 边界的颜色如果没有透明度,为纯色的话,会遮盖其它无边界的波纹。
有边界
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#4285f4"><!--波纹点击颜色-->
<!-- 添加边界 -->
<item android:drawable="@color/blue"/>
</ripple>
上面的 item 是为了设置一个边界,其实它的作用就是为 View 绘制一个默认的背景。并且如果有更复杂的 需求,可以直接在 <item><shape/></item> 中绘制一个 shape 。
button的触摸反馈
Button 在 v21 以上默认情况下是自带有 ripple 效果和点击Z轴抬高的阴影效果(会在视图状态动画中详解)的。
但是如果你给 Button 设置了背景图,上面自带的默认点击效果都会失去。这时如果想保持点击效果有下面几种方式:
- 把 Button 的背景设置放到 Theme 中更改
<style name="AutoButton" parent="AppTheme">
<item name="buttonStyle">@style/Widget.AppCompat.Button</item>
<item name="colorButtonNormal">?attr/colorAccent</item>
</style>
然后把这个 theme 设置给 Button,其中 clolorButtonNormal 就是默认状态下的背景(无需再设置 background )。这样就会保持按钮默认的点击效果。
-
给 Button 设置普通背景的同时,设置 Ripple 效果给 Foreground 前景属性
-
自定义 Ripple
一种形式就是通过上面 自定义有边界 中介绍的自定义 ripple。
如果想设置不同状态的可以通过下面的形式:
<?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_bg1"
android:state_pressed="true">
</item>
<item
android:drawable="@drawable/icon_bg2"
android:state_pressed="false">
</item>
</selector>
</item>
</ripple>
也就相当于把 Ripple 和 Shape 结合在一起。
** 注意,在自定义 <ripple/> 时,一般把它放到 drawable-v21 文件夹下, 在 drawable 文件夹下放置兼容低版本的普通 Drawable 文件,如 <shape/> 或者 <selector/>。 **