RippleDrawableAndroid Ripple效果是Material Design中核心的视觉反馈机制。RippleDrawable 是Android 5.0API 21引入的全新Drawable子类位于android.graphics.drawable 包中。它继承自LayerDrawable 所以它是分层的。实现机制在Android 5.0及以上系统中 RippleDrawable 通过硬件加速渲染机制进行高效绘制。其内部使用了 Canvas 和 RenderThread 进行波纹动画的绘制。当用户触发点击事件时系统会调用RippleDrawable 的 setHotspot(float x, float y) 方法设置热点位置并调用 start() 方法启动波纹动画。动画通过 ValueAnimator 实现动态改变波纹半径 mRadius 并在 draw(Canvas canvas) 方法中绘制圆形波纹。Android框架为Material风格提供了两个预设的主题属性用于快速启用Ripple反馈?attr/selectableItemBackground 带边界的波纹效果通常用于列表项或按钮有界Ripple可避免波纹过度蔓延影响界面整洁。?attr/selectableItemBackgroundBorderless 无边界波纹可超出父容器范围适用于悬浮操作按钮或全屏点击区域。这两个属性是主题级别的引用指向系统内部定义的RippleDrawable资源把它们设置给控件的android:background即可。它们的优点在于无需手动创建XML文件即可获得一致的视觉反馈。Android自5.0API 21引入Material Design以来RippleDrawable成为触摸反馈系统的核心组成部分。通过在XML资源文件中声明Ripple效果开发者可以轻松实现符合Material设计语言的交互体验而无需编写复杂的动画逻辑。自定义Ripple XML资源文件使用ripple 标签自定义Ripple资源必须指定 android:color 作为波纹颜色。一个典型的自定义Ripple资源如下所示!-- res/drawable/ripple_custom.xml --ripple xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:color#FF4081item android:idandroid:id/backgroundshape android:shaperectanglesolid android:color#FFFFFF /corners android:radius8dp //shape/item/ripple此资源定义了一个粉红色波纹 #FF4081 底层背景为白色圆角矩形。在Button、ImageView等控件中设置Ripple效果最常见的应用场景之一是为 Button 添加Material风格的点击反馈。Buttonandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:textClick Meandroid:backgrounddrawable/ripple_customstylestyle/Widget.MaterialComponents.Button.TextButton /此处使用了自定义Ripple资源 drawable/ripple_custom 并配合Material Components库的文本按钮样式确保语义一致性。注意若直接使用原生Button而不继承Material样式可能导致内边距或字体样式不符合规范。代码方式设置Ripple效果val outValue TypedValue() context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true) imageView.foregroundcontext.getDrawable(outValue.resourceId)Ripple与Selector资源的对比与整合传统Android开发中广泛使用 StateListDrawable 即Selector来实现不同状态下的背景切换。随着Ripple的引入两者的关系变得复杂。Selector vs Ripple核心差异特性状态管理Selector支持 pressed 、 focused 、 disabled 等Ripple主要响应 pressed 状态。视觉形式Selector静态切换如换图、变色Ripple主动态动画波纹扩散。资源开销 Selector极低Ripple主中等GPU绘制动画层。Material合规性Selector不符合Ripple主符合。尽管Ripple更适合现代UI但在某些场景仍需结合Selector使用。整合方案Ripple Selector作为背景层设想一个按钮在“启用”和“禁用”状态下有不同的底色同时启用Ripple反馈!-- res/drawable/bg_button_ripple.xml --ripple xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:color#40000000item android:idandroid:id/backgroundselectoritem android:state_enabledfalseshape android:shaperectanglesolid android:color#E0E0E0 /corners android:radius8dp //shape/itemitem android:state_pressedtrueshape android:shaperectanglesolid android:color#BBDEFB /corners android:radius8dp //shape/itemitemshape android:shaperectanglesolid android:color#FFFFFF /corners android:radius8dp //shape/item/selector/item/ripple此方案利用 selector 作为Ripple的背景层实现状态感知的底色变化同时保留波纹动画。当按钮被禁用时即使点击也不会触发Ripple——这是由系统自动控制的。执行逻辑分析用户点击控件 → 系统检测 android:clickable 和 android:enabled 状态。若控件可用则启动Ripple动画层否则跳过。背景层根据当前状态选择对应 item 进行渲染。波纹以触摸点为中心展开持续约150ms后淡出。这种方式兼顾了功能性与美观性是企业级应用中常见的模式。Ripple在不同Android版本上的兼容处理Ripple是Material Design的重要特征但它仅在API 21及以上版本原生支持。在5.0以下版本常用的替代方案包括普通颜色切换 使用 Selector 改变背景色透明度动画 通过 alpha 变化模拟按压感帧动画 预设一系列图片形成“伪波纹”Android Ripple背景效果实现详解与实战/* 给ViewHolder视图添加点击波纹效果或者在列表项布局文件中添加属性 android:clickabletrue android:background?attr/selectableItemBackground */ public static void setViewHolerRipple(View view){ //这三行代码实现点击有水波纹效果 TypedValue typedValue new TypedValue(); view.getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true); view.setBackgroundResource(typedValue.resourceId); view.setClickable(true); }