【Android】自定义View —— 水波纹

【关键词】

水波纹 涟漪 自定义View

【问题】
  • 通过自定义 View 实现点击时出现水波纹的效果;
【效果图】

ripple_view.gif【Android】自定义View —— 水波纹_第1张图片

【分析】
  • 按下时,获取当前触摸点的坐标;
  • 以当前触摸点(Action_down 和 Action_move)为圆心,不断画圆;
  • 按下时开始绘制波纹,且速度较慢;
  • 松开后加快绘制速度,直到结束;
【解决方案】
  • 在 onDraw 中,不断地增加圆的半径,并不断地画圆,直到圆的半径达到最大值;一次画完之后,调用 postInvalidateDelayed(16); 延时重绘;
  • 设一个 mSlow 变量,按下时设置为true, 松开后设置为 false, 在绘制圆的过程中根据这个变量的值来动态改变半径的增量值;
【代码】

用法
[layout - view_ripple.xml]

  
  
  
  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
 
<com.lyloou.android.view.RippleView
android:layout_margin="16dp"
android:layout_width="200dp"
android:layout_height="80dp" />
</LinearLayout>

[activity]

  
  
  
  
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.view_ripple);
super.onCreate(savedInstanceState);
}

源码
[view]

  
  
  
  
public class RippleView extends View {
private Paint mPaint;
 
private boolean mSlow;
private int mCurrentR;
private int mCenterX = -1;
private int mCenterY = -1;
 
public RippleView(Context context) {
this(context, null);
}
 
public RippleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
 
public RippleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
 
 
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mCenterX = (int) event.getX();
mCenterY = (int) event.getY();
downStart();
return true;
case MotionEvent.ACTION_MOVE:
mCenterX = (int) event.getX();
mCenterY = (int) event.getY();
break;
case MotionEvent.ACTION_UP:
upEnd();
break;
}
return super.onTouchEvent(event);
}
 
private void downStart() {
mSlow = true;
mCurrentR = 0;
postInvalidate();
}
 
private void upEnd() {
mSlow = false;
postInvalidate();
}
 
 
 
@Override
protected void onDraw(Canvas canvas) {
// 画背景
canvas.drawColor(Color.DKGRAY);
 
int maxR = Math.max(getWidth(), getHeight());
 
boolean isInit = mCenterX ==-1 && mCenterY == -1;
if (!isInit && mCurrentR < maxR) {
int unit = mSlow ? maxR / 200 : maxR / 10;
mCurrentR = mCurrentR + unit;
// 颜色透明度随着半径的不断增加而越来越透明
int color = Color.argb((int) ((1-mCurrentR*1.0f/maxR)*255), 88, 120, 22);
mPaint.setColor(color);
canvas.drawCircle(mCenterX, mCenterY, mCurrentR, mPaint);
postInvalidateDelayed(16);
}
 
super.onDraw(canvas);
}
}
【参考资料】
  • Android L中水波纹点击效果的实现;

你可能感兴趣的:(android)