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

【关键词】

水波纹 涟漪 自定义View

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

ripple_view.gif

【分析】
  • 按下时,获取当前触摸点的坐标;
  • 以当前触摸点(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);
}
}
【参考资料】
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
自定义一个水波进度 View,你需要完成以下几个步骤: 1. 创建一个自定义 View 类,并在构造函数中初始化一些必要的属性,如颜色、线宽等。 2. 重写 onSizeChanged() 方法,在该方法中获取 View 的宽度和高度,并计算出进度条的半径、圆心等相关参数。 3. 重写 onDraw() 方法,在该方法中绘制水波纹效果。 4. 在自定义 View 中添加一个 setProgress() 方法,用于设置进度条的进度。 5. 在布局文件中引入自定义 View,设置 layout_width 和 layout_height 属性,并在代码中调用 setProgress() 方法设置进度条的进度。 下面是一个简单的自定义水波进度 View 的代码示例: ```java public class WaterWaveProgressView extends View { private Paint mPaint; private int mWidth, mHeight; private float mRadius; private float mProgress; public WaterWaveProgressView(Context context) { super(context); init(); } public WaterWaveProgressView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public WaterWaveProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.BLUE); mPaint.setStrokeWidth(5); mPaint.setStyle(Paint.Style.STROKE); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; mRadius = Math.min(mWidth, mHeight) / 2 * 0.8f; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaint); float angle = mProgress / 100 * 360; canvas.drawArc(mWidth / 2 - mRadius, mHeight / 2 - mRadius, mWidth / 2 + mRadius, mHeight / 2 + mRadius, -90, angle, false, mPaint); } public void setProgress(float progress) { mProgress = progress; invalidate(); } } ``` 通过调用 setProgress() 方法来更新进度条的进度,如下所示: ```java WaterWaveProgressView progressView = findViewById(R.id.progress_view); progressView.setProgress(50); // 设置进度为 50% ``` 在布局文件中引入自定义 View: ```xml <com.example.waterwaveprogressview.WaterWaveProgressView android:id="@+id/progress_view" android:layout_width="150dp" android:layout_height="150dp" /> ``` 这样就能够实现一个简单的水波进度 View 了。如果需要更加复杂的效果,可以在 onDraw() 方法中绘制多个水波纹,或者使用 Path 绘制波形等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值