项目源码比较简单,直接看帖的代码就可以了。

说实话,我是真没有去看RippleView的源码,只是从表面看到它的效果,所以产生了一点思路,所以功能很有局限性,而且用起来也比较复杂,大家且看且喷就好^_^。

大致的思路就是在需要波纹效果的视图上叠加一层View,在下层View需要触发波纹效果时,绘制一个从中心扩散的圆,或从四周往中心收缩的圆,只要控制好透明度和颜色还有绘制频率,即可仿效出RippleView的效果。

下面贴出代码:

package com.ykb.json.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * com.ykb.json.customview
 * 描述 :简单的水波视图
 * 作者 : ykb
 * 时间 : 15/8/12.
 */
public class WaveView extends TextView
{
    private String TAG = getClass().getSimpleName();
    /**
     * 延迟重绘的时间 ms
     */
    private static final long DRAW_DELAY_MILLS = 15;
    /**
     * 半径的增量
     */
    private static final long RADIUS_INCREMENT_BLOCK = 50;

    /**
     * 波纹模式 -扩散
     */
    public static final int WAVE_MOD_SPREAD = 1;
    /**
     * 波纹模式 -收缩
     */
    public static final int WAVE_MOD_SHRINK = WAVE_MOD_SPREAD+1;
    /**
     * 防止多次加载
      */
    private boolean loadOnce;
    /**
     * 画笔
     */
    private Paint mPaint;
    /**
     * 屏幕像素密度
     */
    private float density;
    /**
     * 占据宽度
     */
    private int width;
    /**
     * 占据高度
     */
    private int height;
    /**
     * 波纹颜色
     */
    private int waveColor = Color.LTGRAY;
    /**
     * 波纹透明度
     */
    private int waveAlph =255;
    /**
     * 波纹渲染半径
     */
    private int radius;
    /**
     * 是否绘制
     */
    private boolean needDraw;
    /**
     * 是否回调最后的波纹颜色
     */
    private boolean changeColor;
    /**
     * 波纹模式 {@link #WAVE_MOD_SHRINK}收缩,{@link #WAVE_MOD_SPREAD}扩散
     */
    private int mode=WAVE_MOD_SPREAD;
    /**
     * 波纹绘制完成后的回调
     */
    private OnWaveCompleteListener callback;
    /**
     * 圆心的横坐标
     */
    private int centerX;
    /**
     * 圆心纵坐标
     */
    private int centerY;
    /**
     * 是否响应touch事件
     */
    private boolean repTouch;


    public WaveView(Context context)
    {
        this(context, null);
    }

    public WaveView(Context context, AttributeSet set)
    {
        this(context, set, 0);

    }

    public WaveView(Context context, AttributeSet set, int defaultStyle)
    {
        super(context, set, defaultStyle);
    }
    /**
     * 设置是否响应touch事件
     */
    public void setRepTouch(boolean repTouch)
    {
        this.repTouch = repTouch;
    }
    /**
     * 设置是否需要返回颜色
     * @param changeColor
     */
    public void setChangeColor(boolean changeColor)
    {
        this.changeColor = changeColor;
    }

    /**
     * 设置波纹展现模式
     * @param mode {@link #WAVE_MOD_SHRINK}收缩,{@link #WAVE_MOD_SPREAD}扩散
     */
    public void setMode(int mode)
    {
        this.mode = mode;
    }
    /**
     * 开始绘制
     */
    public void startDraw(){
        if(!repTouch){
            centerX=width/2;
            centerY=height/2;
        }
        startInvalidate();
    }
    /**
     * 开始绘制
     */
    private void startInvalidate(){
        needDraw=true;
        resetPaint();
        switch (mode){
            case WAVE_MOD_SHRINK:
                radius=width;
                break;
            case WAVE_MOD_SPREAD:
                radius=0;
                break;
        }
        invalidate();
    }
    /**
     * 设置是否可以画
     *
     * @param needDraw
     */
    public void setNeedDraw(boolean needDraw)
    {
        this.needDraw = needDraw;
    }

    /**
     * 设置波纹透明度
     *
     * @param waveAlph
     */
    public void setWaveAlph(int waveAlph)
    {
        this.waveAlph = waveAlph;
    }

    /**
     * 设置波纹颜色
     *
     * @param waveColor
     */
    public void setWaveColor(int waveColor)
    {
        this.waveColor = waveColor;
    }

    /**
     * 设置波浪完成后的回调接口
     * @param callback
     */
    public void setCallback(OnWaveCompleteListener callback)
    {
        this.callback = callback;
    }
    /**
     * 初始化
     */
    private void onLayoutInit()
    {
        density = getResources().getDisplayMetrics().density;
        width = getWidth();
        height = getHeight();
        mPaint = new Paint();
        resetPaint();
        loadOnce = !loadOnce;
    }

    /**
     * 画笔重置
     */
    private void resetPaint()
    {
        mPaint.reset();
        mPaint.setAntiAlias(true);
    }

    /**
     * 清除画布
     * @param canvas
     */
    private void clearCanvas(Canvas canvas)
    {
        canvas.restore();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom)
    {
        super.onLayout(changed, left, top, right, bottom);
        if (changed && !loadOnce) {
            onLayoutInit();
        }
    }

    @Override
    public boolean onTouchEvent( MotionEvent event)
    {
        if(!repTouch)
            return  super.onTouchEvent(event);

        int action=event.getAction();
        Log.e("onTouch,action : "+action);
        if(action==MotionEvent.ACTION_UP){
            centerX=(int)event.getX();
            centerY=(int)event.getY();
            startInvalidate();
        }

        return  super.onTouchEvent(event);
    }

    @Override
    public void draw(Canvas canvas)
    {
        super.draw(canvas);
        boolean end=false;
        switch (mode){
            case WAVE_MOD_SHRINK:
                if(radius<=0)
                    end=true;
                break;
            case WAVE_MOD_SPREAD:
                if(radius >= width / 2)
                    end=true;
                break;
        }

        if (!needDraw||end) {
            if(null!=callback&&needDraw&&changeColor) {
                callback.onWaveComplete(waveColor);
            }
            clearCanvas(canvas);
            return;
        }

        if(radius==(mode==WAVE_MOD_SPREAD?0:width))
            canvas.save();

        mPaint.setColor(waveColor);
        mPaint.setAlpha(waveAlph);
        canvas.drawCircle(centerX, centerY, radius, mPaint);
        radius += (mode==WAVE_MOD_SPREAD?RADIUS_INCREMENT_BLOCK:-RADIUS_INCREMENT_BLOCK);
        postInvalidateDelayed(DRAW_DELAY_MILLS);
    }
    /**波纹绘制完成的回调接口**/
    public interface OnWaveCompleteListener{
        public void onWaveComplete(int color);
    }
}

代码就是这么简单,在使用的时候只需按自己的需求叠加到相应的控件上,然后设置好相关属性,调用startDraw方法即可。

-布局使用如下

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_40"
        android:layout_marginLeft="@dimen/dimen_40"
        android:layout_marginRight="@dimen/dimen_40"
        android:layout_marginTop="@dimen/dimen_40">
        <Button
            android:id="@+id/btn_login_bg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/title_bg1"
            />
        <com.ykb.json.customview.WaveView
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:id="@+id/layout_login"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.ykb.json.customview.WaveView>
        <Button
            android:id="@+id/btn_login"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@null"
            android:text="登  录"
            android:textColor="@color/white"
            android:textSize="@dimen/dimen_18"/>

    </RelativeLayout>

-代码使用如下

private void initUI() {
    layout_login=(WaveView)findViewById(R.id.layout_login);
    layout_login.setCallback(this);
    layout_login.setMode(WaveView.WAVE_MOD_SHRINK);
    layout_login.setChangeColor(true);
}
@Override
public void onClick(View v) {
    layout_login.startDraw();
}   

@Override
public void onWaveComplete(int color){
    btn_login_bg.setBackgroundColor(color);
}

写完这篇博客后我就去看看RippleView的实现原理,我知道这个波纹效果肯定差它差的太远,但是依然希望有大神提供更好的思路,给我们这些初学者学习更多的自定义View知识。