RippleView(波纹按钮)的效果实现

原创 2015年07月10日 18:13:05

Android M已经发布,但是很多机器才升级到Android L,升级到L之后我们发现很多的按钮点击的时候会有一圈波纹扩散出去的效果,炫酷到没朋友。但是不是所有的版本上都有这个效果的,怎么办呢?有大神开发出了一个nineOldAndroid的动画包,我们可以使用里面的api做自定义的开发这样就可以用到各种版本上面了。

传送门在此:

http://nineoldandroids.com/

https://github.com/JakeWharton/NineOldAndroids


我找到了这么一个图,类似于下面的效果,我只是非常简单的说下具体是怎么实现的,如果想做的更好一点请自己包装开发,只说关键代码,代码有参考下面的工程。

此图和代码的传送门https://github.com/siriscac/RippleView



public class RippleView extends Button {
    private PointF touchPoint = new PointF();
    private int radius = 150;
    private Paint mPaint;
    private ObjectAnimator objectAnimator;

    public RippleView(Context context) {
        super(context);
        init();
    }

    public RippleView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public RippleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAlpha(100);
        mPaint.setColor(Color.GREEN);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchPoint.x = event.getX();
            touchPoint.y = event.getY();
            radius = 150;
            setRadius(150);
            break;
        case MotionEvent.ACTION_MOVE:
            touchPoint.x = event.getX();
            touchPoint.y = event.getY();
            setRadius(150);
            break;
        case MotionEvent.ACTION_UP:
            objectAnimator = ObjectAnimator.ofFloat(this, "radius", 150, 1000).setDuration(400);
            objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
            objectAnimator.addListener(new AnimatorListener() {

                @Override
                public void onAnimationStart(Animator arg0) {

                }

                @Override
                public void onAnimationRepeat(Animator arg0) {

                }

                @Override
                public void onAnimationEnd(Animator arg0) {
                    setRadius(0);
                }

                @Override
                public void onAnimationCancel(Animator arg0) {

                }
            });
            objectAnimator.start();
            break;
        }
        return super.onTouchEvent(event);
    }

    /** 根据给定的color和alpha值得到给定的color */
    public int getColor(int color, float aAlpha) {
        int alpha = Math.round(Color.alpha(color) * aAlpha);
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);
        return Color.argb(alpha, red, green, blue);
    }

    /** 在执行ObjectAnimator的过程中就会调用此方法 */
    public void setRadius(float radius) {
        System.out.println("setRadius----------" + radius);
        this.radius = (int) radius;
        if (this.radius > 0) {
            RadialGradient mRadialGradient = new RadialGradient(touchPoint.x, touchPoint.y, this.radius, getColor(
                    Color.GREEN, 0.1f), Color.GREEN, Shader.TileMode.MIRROR);
            mPaint.setShader(mRadialGradient);
        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawCircle(touchPoint.x, touchPoint.y, radius, mPaint);
        super.onDraw(canvas);
    }
}

主要的思想是这样的:重写onDraw()和onTouchEvent(),在onDraw中根据得到的手指的位置画一个圆,给定半径和画笔。在手指移动的时候也圆中心点的坐标也会跟着移动。当手指抬起来的时候触发动画。

objectAnimator = ObjectAnimator.ofFloat(this, "radius", 150, 1000).setDuration(400);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();


这是动画的关键代码,首先我们使用ObjectAnimator.ofFloat这个工厂方法得到一个ObjectAnimator的对象,然后赋予执行时间和Interpolator,也就是动画的变化效果,我们这里没有使用变化效果。

start之后在执行中会不断的调用setRedius(Float)方法,并不断传入最新的redius的值,这时候我们需要做的是不断修改当前redius的值并且刷新界面画新圆。

期间我们用到了RadialGradient方法。

android.graphics.RadialGradient.RadialGradient(float x, float y, float radius, int color0, int color1, TileMode tile)

Create a shader that draws a radial gradient given the center and radius.

Parameters:
x The x-coordinate of the center of the radius
y The y-coordinate of the center of the radius
radius Must be positive. The radius of the circle for this gradient
color0 The color at the center of the circle.
color1 The color at the edge of the circle.
tile The Shader tiling mode

我们可以看出各个参数的信息。大体就是这样,还有一个比较好玩的就是getColor这个方法,是根据给定的色值和alpha得出需要显示的color的值。其中几个Color的静态方法比较有意思,比如Color.red(color)

<pre name="code" class="html">int android.graphics.Color.red(int color)

Return the red component of a color int. This is the same as saying (color >> 16) & 0xFF

Parameters:
color 

它说same as (color >> 16) & 0xFF,如果去看源码的话也是这么实现的
    /**
     * Return the red component of a color int. This is the same as saying
     * (color >> 16) & 0xFF
     */
    public static int red(int color) {
        return (color >> 16) & 0xFF;
    }
我们假如说我们有一个色值0xFF00FF00,转成二进制就是11111111000000001111111100000000,然后右移16位就是00000000000000001111111100000000然后需要跟0xFF取与,得到00000000,也就是0x00。

跑题了,谢谢观赏。

RippleView水波纹,涟漪效果

模仿水波纹,涟漪效果,可用于设备查找之类的特效Demo下载:我的Github RippleView其实这是一个很简单的自定义View,只需要一个类,然后对外提供状态回调接口和设置属性的方法即可。下面要...
  • Ru_Zhan
  • Ru_Zhan
  • 2016年07月02日 18:17
  • 1348

Android之水波纹点击效果(RippleView)

Android5.0后各种炫的效果纷纷出来,写这篇博客主要是讲的是按钮点击效果带有的水波纹(波浪式)。 当然我写的这个是自定义来实现的,在低版本(5.0一下)也可以实现点击效果。看看效果图:     ...
  • DickyQie
  • DickyQie
  • 2017年03月24日 17:59
  • 494

[Android L]Android L RippleView 效果 低版本实现

从github上看到的一个实现Android L RippleView效果的比较好的一个实例 使用简单 方法一:代码中添加,view为需要实现效果的控件 MaterialRipp...
  • pengjian1993
  • pengjian1993
  • 2015年03月13日 20:48
  • 1353

Android 5.0+ 自定义普通按钮的ripple波纹效果

Android 5.0中新增了ripple类型,即波纹效果 在res中添加一个新的文件夹drawable-v21,用于保存波纹效果 button_ripple_orange.xml ...
  • jdsjlzx
  • jdsjlzx
  • 2016年03月10日 17:00
  • 13688

Android Ripple的详解

转自:Android L Ripple的使用总纲 没有边界的Ripple(Ripple With No Mask) 用颜色作为Mask的Ripple(Ripple With Color Mask),然...
  • AwayEagle
  • AwayEagle
  • 2016年09月19日 11:02
  • 3232

<android5.0>之Ripple水波纹效果

android 5.0 拥有ripple效果, 非常漂亮
  • u011748648
  • u011748648
  • 2015年11月13日 14:59
  • 6484

android点击的ripple效果

android的ripple
  • zyjzyj2
  • zyjzyj2
  • 2016年12月07日 23:26
  • 396

Material Design之RippleDrawable详解

Material Design之RippleDrawable详解自从android5.0开始以后,google就推出了一套UI设计语言materialdesign,俗称:材料设计。其中一个最直观的效果...
  • oQiHaoGongYuan
  • oQiHaoGongYuan
  • 2016年11月09日 17:39
  • 3354

Android 5.0+ 自定义普通按钮的ripple波纹效果

在Android L5.0中加入了触摸反馈动画。其中最明显,最具代表性的就是波纹动画,比如当点击按钮时会从点击的位置产生类似于波纹的扩散效果。波纹效果(Ripple):当你使用了Material主题后...
  • jdsjlzx
  • jdsjlzx
  • 2016年05月31日 17:05
  • 2891

Android L限制Ripple水波纹范围大小

Ripple简介Android 5.0之后google推出了Material Design,Botton默认的触摸反馈会有水波纹涟漪效果。而这种水波纹的效果实现主要依赖于RippleDrawable。...
  • kong92917
  • kong92917
  • 2017年01月09日 17:44
  • 3088
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RippleView(波纹按钮)的效果实现
举报原因:
原因补充:

(最多只允许输入30个字)