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
  • 1237

RippleView(仿照5.0点击有波浪效果)

public class RippleView extends RelativeLayout { private int WIDTH; private int HEIGHT; ...

NavigationView下Menu点击切换Fragment的卡顿解决方法

项目中用到侧滑导航,点击导航切换Fragment时,菜单回弹会有很明显的卡顿。 首先想到的是Fragment的优化,是不是Fragment在OnCreateView的时候做了太多的工作。 方案1:将F...

使用NavigationView 进行导航栏的设计

Navigation View 抽屉导航是app识别度与内部导航的关键,保持这里设计上的一致性对app的可用性至关重要,尤其是对于第一次使用的用户。 NavigationView 通过提供抽屉导...

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

  • 2017年03月24日 18:02
  • 25.76MB
  • 下载

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

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

Android中按钮的水波纹点击效果的实现

关于按钮水波纹的点击效果,这个是我在http://blog.csdn.net/singwhatiwanna/article/details/42614953这篇文章读到的。写得真心不错,我只是站在巨人...

自定义按钮实现水波纹效果

如果你的Android手机是5.0以上的系统,相信对下面这种按钮点击效果并不会陌生: 实现效果图点击此网址查看:http://www.runoob.com/wp-content/uploads/...

Android 中实现5.0按钮水波纹反馈效果

自从android L(android 5.0)出来了, 在界面上有了很大的改动,变得扁平化了,很多控件增加了不错的效果,相信大家对view的点击出现会波纹效果都有所体验吧,点击一个view,然后一个...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RippleView(波纹按钮)的效果实现
举报原因:
原因补充:

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