Ripple水波纹涟漪效果

Ripple在material_design中使用,需要对非-v21进行兼容,在-21以下的情况下使用的是selector,两种效果:一种透明(默认),一种是点击后的效果。

官方地址:RippleDrawable
从官方文档了解到设置使用中就两种区别:就是添不添加android:id="@android:id/mask"的区别

1
2
3
4
<ripple android:color="@color/gray">
<item android:id="@android:id/mask"
android:drawable="@android:color/white" />

</ripple>

英文不太好的人只能通过测试才知道有什么不同:

添加mark后,点击是gray和white逐渐加载出来。而不添加mark的时候,默认显示white,点击只加载gray

使用:

Ripple的效果再有在api21以后才有效果,所以使用的时候需要新建一个drawable-v21的文件夹后,新建两个ripple_xx.xml分别放在drawable和drawable-v21中。如下:(圆角的水波涟漪效果)

  • drawable文件夹,使用<selector>:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="@color/ripple_light" />
<corners android:radius="@dimen/dp_7" />
</shape>
</item>
<item>
<shape>
<solid android:color="@color/transparent" />
<corners android:radius="@dimen/dp_7" />
</shape>
</item>
</selector>

设置android:state_pressed的属性,关键在与color的设置,默认要为透明

  • drawable-v21文件夹,使用<ripple>:
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/ripple_light">

<item
android:id="@android:id/mask">

<shape>
<solid android:color="@color/white"/>
<corners android:radius="@dimen/dp_7"/>
</shape>
</item>
</ripple>

最后注意的是:

是放置的位置,需要放在子布局中,否则无法显示出来,我就是调试了1个下午才发现这个问题。脑子不好使。
而且,为了这种涟漪的效果,需要额外加多一层布局进行实现,耗掉不少的资源和速度。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<RelativeLayout
android:id="@+id/btn_register"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
android:background="@drawable/shape_login_register">


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/ripple_login_corner">


<TextView
style="@style/LoginBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_login_register"
android:text="注册" />

</RelativeLayout>
</RelativeLayout>

上面这种是很不明智的做法,根据xml中view的递归加载,嵌套的情况是最耗费的资源的,换一种思路:

我们需要的是涟漪效果而已,把这种效果交给额外的view去做,而这个view放在了跟我们button同一个位置,那么点击button,一样会触发此view,效果达到,又不需要再进行嵌套。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<RelativeLayout
android:id="@+id/btn_register"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
android:background="@drawable/shape_login_register">

<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/ripple_login_corner" />

<TextView
style="@style/LoginBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_login_register"
android:text="注册" />

</RelativeLayout>

资料:

解决点击ripple水波纹无效的问题