Material Design 之 Touch Feedback
2017-10-20 17:44
246 查看
目录
目录概要
设置触摸反馈
RippleDrawable
参考链接
概要
在 Materil Design(一下简称 MD ) 中,当用户与 UI 交互的时候,触摸反馈(Touch Feedback)可以在交互点提供一种及时的视觉确认效果。设置触摸反馈
Button 在 MD 中默认就有一个反馈动画,使用的是 RippleDrawable 类,这个类很有意思,它根据手指与 UI 交互的不同状态(例如,长按,短按,抬起)转化为不同的波纹效果(Ripple Effect)。 这个效果就不演示了,相信大家已经都看烂了。然而,并不是所有的控件都有默认的触摸反馈的波纹效果,例如 TextView,那么,怎么给这些控件添加触摸反馈的波纹效果呢?
可以使用系统提供的两个属性来在 XML 中给 View 设置背景,也就是
android:background
?android:attr/selectableItemBackground提供了有边界的波纹效果
?android:attr/selectableItemBackgroundBorderless提供了无边界的波纹效果
selectableItemBackgroundBorderless在 API 21 才可用。
在 RelativeLayout 中添加一个 TextView 并居中显示
<TextView android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:clickable="true" android:gravity="center" android:text="设置触摸反馈效果"/>
TextView 的属性,我特意设置了一个可点击的属性
android:clickable,这样才能响应点击事件,后面才能看到波纹效果。
在 Android Studio 中效果如下
TextView 默认是没有边界的,当我们点击 TextView 后,发现并没有任何触摸反馈的效果(即使设置了可点击啊属性)。
那么,按照前面说的,给 TextView 设置一个触摸反馈的背景属性,例如,先设置了一个有边界的波纹属性
<TextView android:background="?android:attr/selectableItemBackground" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:clickable="true" android:gravity="center" android:text="设置触摸反馈效果"/>
当点击 TextView 后,效果如下
可以看到两个效果
1.会以触摸点为中心,形成一个波纹效果
2.TextView 显示出了边界
有些时候,我们需要 TextView 响应点击事件,但是并不需要 TextView 显示边界。例如,在微博中,点击一个用户的名字,会跳转到用户相关的页面,如果在点击名字的时候,出现了边界,是不是有点丑陋? 反正我觉得有点丑的。
那么,如果我们既想有点击波纹效果,又不想出现边界,就可以用系统提供的无边界波纹效果
<TextView android:background="?android:attr/selectableItemBackgroundBorderless" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:clickable="true" android:gravity="center" android:text="设置触摸反馈效果"/>
当点击 TextView 的时候,你只会看到一个波纹效果,而并没有出现边界,如下图所示。
系统波纹的颜色是一个淡灰色,我们可以换换
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorControlHighlight">@color/colorAccent</item> </style>
RippleDrawable
系统提供的波纹效果,是一个灰色的波纹效果,那么如果我们想自定义的波纹的颜色呢?前面提到过,Button 默认的触摸反馈效果,是用 RippleDrawable 类实现的,可以在 XML 中定义一个 Ripple Drawable。
res/drawable/ripple.xml
<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorPrimary"> </ripple>
我给这个 RippleDrawable 定义了一个颜色
android:color="@color/colorPrimary",这就是波纹的颜色。
现在把这个 Ripple Drawale 设置为 TextView 背景
<TextView android:background="@drawable/ripple" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:clickable="true" android:gravity="center" android:text="设置触摸反馈效果"/>
点击 TextView 效果如下
由于用的是模拟器,因此这个波纹不是很明显,如果在真机上,可以明显看到一个波纹效果,而这个波纹颜色,就是刚才设置。
那么,现在长按下,可以看到如下效果
ok,这个长按效果不纠结了,知道这么回事就行了。
那么现在有一个问题,怎样才能像 Button 的波纹效果一样,大小限制在整个 Button 内呢?
RippleDrawable 是继承自 LayerDrawable,所以可以加一层 layer,来限制波纹的大小。
<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorPrimary"> <item android:drawable="@android:color/white"/> </ripple>
再点击 TextView 后,会有如下效果
看懂这个效果后,可能有人会问了,刚才你不是说到给 TextView 设置有带边框的波纹很丑吗? 是的,确实丑。
然而在开发中,我们还可能遇到一种情况,例如 CardView 本身也是没有触摸反馈效果的,但是它有边界,如果在 CardView 上添加这个有边界的波纹,这样就不丑了吧?具体效果,就留给大家自己去试试了。
其实 RippleDrawable 还有一个很有意思的事情,它又一个遮罩层,id 为
android.R.id.mask,既然叫做遮罩层,那就是限制波纹的范围了。
刚才看到有界的波纹的范围其实就是 TextView 的大小范围,那么可以用遮罩层来改变这个范围的形状,如果大家清楚图像混合的几种模式,这就很好理解了。
首先为 RippleDrawable 加一个 layer,用来定义遮罩层
<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorPrimary"> <item android:drawable="@android:color/white"/> <item android:id="@android:id/mask" android:drawable="@drawable/ripple_mask"/> </ripple>
注意,遮罩层的 id 一定要定义为
@android:id/mask
再看看 res/ripple_mask.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@android:color/holo_red_light"/> </shape>
形状定义为了 oval,系统会自动根据 TextView 的大小来决定是圆形还是椭圆。
如果按照图像混合原理来看,其实这里的颜色的透明度只要是不透明的,就能形成遮罩效果,但是从我测试的来看,这里的颜色可以随意设置,也不需要关心透明度。
当我们点击 TextView 的时候,就与无边界的波纹效果一样,只是这个波纹的圆小一点,如下图
刚才说了,到底是椭圆还是圆是根据 TextView 的大小而定的,如果把 TextView 的高度改下
<TextView android:background="@drawable/ripple" android:layout_width="200dp" android:layout_height="100dp" android:layout_centerInParent="true" android:clickable="true" android:gravity="center" android:text="@string/button"/>
现在 TextView 是长方形了,那么再点击的时候,效果如下
现在就是一个椭圆的波纹效果了,是不是很有点意思。
再回到了 res/ripple_mask.xml,刚才我们说到,颜色其实是可以随意定义的,那么我们还要设置这个干嘛? 当然是为了形成 GradientDrawable 对象了。
这里用的是填充的方式来形成 GradientDrawable 对象,当然,我们也可以用描边的方式
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <stroke android:width="10dp" android:color="@android:color/black"/> </shape>
那么点击 TextView ,效果如下
这就有点意思了!
参考链接
https://developer.android.com/training/material/animations.html#Touchhttps://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html
相关文章推荐
- Android Material Design动画 Touch Feedback | 触摸反馈
- Material Design - Touch feedback , Reveal effect
- Touch_Feedback
- Touch Feedback(触摸反馈):水波纹
- material design(三)recycleview的ItemTouchHelper
- Customize-Touch-Feedback
- android Lollipop(5.0)--touch feedback(触摸反馈)
- 开始 Sencha Touch 2 之旅之一
- 【转】MATERIAL DESIGN设计规范学习心得
- vmtouch--the Virtual Memory Toucher
- 附2、MDT 2013 Update 1 引导镜像LiteTouchPE_x64.ISO无法在EFI环境下无法启动的修改办法
- 【专访】感受 TeslaTouch——真正的力反馈屏幕
- dispatchTouchEvent onInterceptTouchEvent onTouchEvent区分
- 移动Web应用开发技术讲解-Sencha Touch 1.1
- Touch Up Inside,Touch down 区别(Xcode 6.4)
- 简单的分析一下sencha touch2
- iOS 9之3D Touch
- Sencha touch 开发中使用Jasmine 进行功能测试
- 移动端开发概览【webview和touch事件】
- 细说UIScrollView上的Touch 事件