Android自定义View(四)——仿Android5.0波纹效果

来源:互联网 发布:python websocket 编辑:程序博客网 时间:2024/06/05 15:57

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

说实话,我是真没有去看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);}@Overridepublic void onClick(View v) {    layout_login.startDraw();}   @Overridepublic void onWaveComplete(int color){    btn_login_bg.setBackgroundColor(color);}

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

1 0
原创粉丝点击