项目源码比较简单,直接看帖的代码就可以了。
说实话,我是真没有去看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知识。