背景+波纹
对于有边界限制的Ripple,我们就需要给他提供一个范围,即添加一个item标签。

  • 如果在一个ripple标签中,添加一个item标签,在item中添加如下属性:
    • 【android:drawable="@color/***"】水波效果会限定在本身矩形区域内部
    • 【android:drawable="@drawable/png等"】水波效果会限定在图片中非透明部分对应的区域内部
    • 【android:drawable="@color/shape"】水波效果会限定在shape对应的区域内部
  • 如果在一个ripple标签中,添加一个item标签,在item中添加一个selector标签,那么将同时具有水波效果和selector效果

item带不带id的区别

添item时,如果不指定id为@android:id/mask,那么不点击时会显示出该item指定的drawable
添item时,如果指定id为@android:id/mask,那么不点击时不会显示出该item指定的drawable,而仅仅在点击的时候才出现
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#F00" >
    <item
        android:id="@android:id/mask"
        android:drawable="@drawable/ic_launcher"/>

</ripple>



实践中发现,这两个属性都是一样的,且和没设置时的效果一样
  • 【android:background="?android:attr/selectableItemBackground"】有边界波纹
  • 【android:background="?android:attr/selectableItemBackgroundBorderless"】超出边界波纹



当ripple标签内只指定一个android:color属性时,则该ripple效果的绘制会溢出其所在View的边界,直接绘制在父控件的背景之上。
如果父控件没有设置背景,则会进一步绘制在父控件的上一级父控件的背景之上。

Ripple生效条件

当 View 有设置 OnClickListener 的情况下被点击,或者获得/失去焦点变化时,将出现Ripple效果
如果点击效果没有,很可能是该控件本身点击没开启,设置如下属性即可【android:clickable="true"】

不适用Ripple的场景

点击之后就立马消失的组件(setVisibility:gone invisible 或 remove)不适合使用
因为当组件恢复为visiable后,未播放完的Ripple动画会继续播放,会产生疑惑

硬件加速开关对无边界Ripple的影响:

在Android 3.0 (API level 11)引入的硬件加速功能默认在application/Activity/View这三个层级上都是开启的。
但如果手动关闭了,则无边界Ripple不会生效。

子层(Child Layer)

由于View在不同的交互下有不同的state,常见的为pressed、focused或normal这三种状态。
所以Ripple通过多个item来表示不同state下的显示,每个item都是一个子层(Child Layer),能够直接显示color、shape、drawable/image 及 selector。
当Ripple存在一个或多个子层时,则ripple效果则被限定在当前View的边界内了。无边界效果(unbounded ripple)失效。

Mask层(Mask Layer)

可以设置指定子层item的android:id="@android:id/mask"来设定当前Ripple的Mask。
Mask的内容并不会被绘制到屏幕上,它的作用是限定Ripple效果的绘制区域。
mask所在的的子层限制了Ripple效果的最大范围只能是View的边界,不会扩散到父组件。

与ClickableSpan冲突

如果Layout有包含ClickableSpan的TextView,则发现该Layout设置Ripple的效果无法响应。
这个现象可以推断出MotionEvent这个事件在TextView这一层级被消耗了,下一步应该为找出该事件为什么被消耗?
通过debug源码,发现当点击事件传递到TextView时,会进一步传递给LinkMovementMethod::onTouchEvent(),如果点击位置处于ClickableSpan以外,则返回Touch.onTouchEvent(widget, buffer, event);
该方法在处理MotionEvent::ACTION_DOWN时默认返回true,导致Ripple失效。
那么解决思路也就简单了,重写LinkedMovementMethod::onTouchEvent()方法,当且仅当点击到ClickableSpan时,才返回true即可。

布局

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="vertical" >
        <Button
            style="@style/textview"
            android:text="在5.0以上,Button默认自带Ripple点击效果" />
        <View style="@style/line" />
        <Button
            style="@style/textview"
            android:background="@drawable/ic_launcher"
            android:text="但是如果设置了其他的background \n Ripple点击效果就没了" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:text="TextView默认是没有Ripple点击效果的" />
        <View style="@style/line" />
        <TextView
            style="@style/textview2"
            android:background="@drawable/_1_default"
            android:text="默认是圆形的、超出边界的波纹\n波纹的直径为控件宽高中的最大值" />
        <View style="@style/line" />
        <TextView
            style="@style/textview2"
            android:background="@drawable/_1_default2"
            android:text=" 但当波纹遇到其他控件的背景时,不会遮挡住其他控件的背景(比如不会挡住下面控件的背景)" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:background="@drawable/_2_color_without_id"
            android:text="用颜色作为Mask,不指定id\n此时item中的颜色会被用来作为点击前的背景颜色" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:background="@drawable/_2_color_with_id"
            android:text="用颜色作为Mask,指定id\n此时item中的颜色没任何卵用,但可以用来限定边界" />
        <View style="@style/line" />
        <TextView
            style="@style/textview3"
            android:background="@drawable/_3_pic_without_id"
            android:text="用图片作为Mask\n不指定id" />
        <View style="@style/line" />
        <TextView
            style="@style/textview3"
            android:background="@drawable/_3_pic_with_id"
            android:text="用图片作为Mask\n指定id" />
        <View style="@style/line" />
        <TextView
            style="@style/textview3"
            android:background="@drawable/_4_shape_without_id"
            android:text="用shape作为Mask\n不指定id,矩形" />
        <View style="@style/line" />
        <TextView
            style="@style/textview3"
            android:background="@drawable/_4_shape_with_id"
            android:text="用shape作为Mask\n指定id,圆形" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:background="@drawable/_5_selector_without_id"
            android:text="搭配selector使用,不指定id \n将同时具有水波效果和selector效果" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:background="@drawable/_5_selector_with_id"
            android:text="搭配selector使用,指定id \n和上面的一样,指定id后选择器效果将丢失" />
        <View style="@style/line" />
        <TextView
            style="@style/textview"
            android:background="@drawable/_5_selector_fuza"
            android:text="这是一种负责的情况" />
    </LinearLayout>

</ScrollView>


样式

<resources>
    <style name="textview">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:gravity">center</item>
        <item name="android:clickable">true</item>
    </style>
    <style name="textview2">
        <item name="android:layout_width">300dp</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:gravity">center</item>
        <item name="android:clickable">true</item>
    </style>
    <style name="textview3">
        <item name="android:layout_width">120dp</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:gravity">center</item>
        <item name="android:clickable">true</item>
    </style>
    <style name="line">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">1dp</item>
        <item name="android:background">#000</item>
    </style>

</resources>


附件列表

Ripple 水波纹效果的更多相关文章

  1. 兼容Android的水波纹效果

    Android的水波纹效果只有高版本才有,我们希望自己的应用在低版本用低版本的阴影,高版本用水波纹,这怎么做呢?其实,只要分drawable和drawablev21两个文件夹就好了. 普通情况下的se ...

  2. 聊聊Android5.0中的水波纹效果

    水波纹效果已经不是什么稀罕的东西了,用过5.0新控件的小伙伴都知道这个效果,可是如果使用一个TextView或者Button或者其它普通控件的话,你是否知道如何给它设置水波纹效果呢?OK,我们今天就来 ...

  3. android 点击水波纹效果

    这里是重点,<ripple>是API21才有的新Tag,正是实现水波纹效果的; 其中<ripple android:color="#FF21272B" .... ...

  4. canvas实现水波纹效果

    本文将会从水波的基本原理开始,详细讲解在canvas中模拟水波扩散,分析并计算水波的能量分布,并通过振幅模拟水波对图像的折射效果,最后实现水波特效. 水波基本原理 首先复习一波高中物理知识. 波是指振 ...

  5. jquery ripples水波纹效果( 涟漪效果)

    这个效果是我从bootstrap-material-design上面分离下来的,bootstrap-material-design的一些组件样式我不太不喜欢,但是非常喜欢这个水波纹效果,所以就有了这篇 ...

  6. 如何使用 HTML5 Canvas 制作水波纹效果

    今天,我们继续分享 JavaScript 实现的效果例子,这篇文章会介绍使用 JavaScript 实现水波纹效果.水波效果以图片为背景,点击图片任意位置都会触发.有时候,我们使用普通的 Javasc ...

  7. android自定义控件(4)-自定义水波纹效果

    一.实现单击出现水波纹单圈效果: 照例来说,还是一个自定义控件,观察这个效果,发现应该需要重写onTouchEvent和onDraw方法,通过在onTouchEvent中获取触摸的坐标,然后以这个坐标 ...

  8. 自定义view实现水波纹效果

    水波纹效果: 1.标准正余弦水波纹: 2.非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余弦函数模拟水波纹效果,另外一个会运用到图像的混合模式(PorterDuffX ...

  9. Android 颜色渲染(七) RadialGradient 环形渲染实现水波纹效果

    利用环形渲染我们可以做到什么? 其实很多都是非常常见的,比如上一篇实现的帮帮糖效果, 彩色的热气球,比如这里要讲到的水波纹效果,或者也可以理解为扩散色渲染效果 首先看一下效果图: 轻触屏幕,即可看到对 ...

随机推荐

  1. HDU 6030 Happy Necklace

    矩阵快速幂. 因为任意素数长度都要满足,所以$3$必须满足,$3$一旦满足,其余的肯定满足,也就是说只要考虑字符串末尾两位即可,$dp$一下就可以算方案数了.$n$较大,可以矩阵加速. #includ ...

  2. 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]

    题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...

  3. Mybatis 源码分析之一二级缓存

    一级缓存 其实关于 Mybatis 的一级缓存是比较抽象的,并没有什么特别的配置,都是在代码中体现出来的. 当调用 Configuration 的 newExecutor 方法来创建 executor ...

  4. shell脚本基本用法

    下面是一些简单常用的脚本,工作中可能会用到,记录一下. #!/usr/bin/env bash #变量[=两边不要有空格], 在使用的时候需要用${变量名} 或者是$变量名 name="sa ...

  5. 【BZOJ 2665】 2665: [cqoi2012]编号(暴力?)

    2665: [cqoi2012]编号 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 347  Solved: 217 Description 你需要给一 ...

  6. 【贪心】hdu4803 Poor Warehouse Keeper

    题意:一开始有1个物品,总价是1.你的一次操作可以要么使得物品数量+1,总价加上当前物品的单价.要么可以使得总价+1,物品数量不变.问你最少要几次操作从初始状态到达有x个物品,总价是y的状态.这里的y ...

  7. hdu 1171 多重背包

    题意:给出价值和数量,求能分开的最近的两个总价值,例如10,20*2,30,分开就是40,40 链接:点我 #include<cstdio> #include<iostream> ...

  8. Unity随手机

    该文章持续更新! 协程的返回值必需是 IEnumerator 协程的参数不能加关键字 ref 或 out 在函数 Update 和 FixedUpdate 中不能使用 yield 语句,但可以启动协程 ...

  9. 《深入理解Spark-核心思想与源码分析》(六)第六章计算引擎

    RDD是Spark对各类数据计算模型的统一抽象,被用于迭代计算过程以及任务输出结果的缓存读写. 在所有MapReduce框架中,shuffle是连接map任务和reduce任务的桥梁.shuffle性 ...

  10. kali 执行apt-get upgrade后,终端无法打开的解决办法

    今天在kali执行apt-get upgrade命令后,reboot启动,发现进入界面终端无法开启 一波百度,google发现大概应该是语言的配置问题,因为最开始安装kali的时候是选择中文,可能up ...