自定义实现水波纹效果
package com.loaderman.mywave; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.loaderman.mywave.MainActivity"> <com.loaderman.mywave.MyWave android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
package com.loaderman.mywave; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.util.ArrayList; import static android.R.attr.radius; public class MyWave extends View { private ArrayList<Wave> mList = new ArrayList<>(); private int[] mColors = new int[]{Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN}; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { flushData(); invalidate(); if (!mList.isEmpty()) {//屏幕还有圆环显示, 就需要继续循环 mHandler.sendEmptyMessageDelayed(0, 50); } } }; public MyWave(Context context) { super(context); } public MyWave(Context context, AttributeSet attrs) { super(context, attrs); } public MyWave(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void flushData() { //遍历集合, 修改所有对象的半径,宽度, 渐变 //半径变大 //宽度变大 //颜色变淡 ArrayList<Wave> killedList = new ArrayList<>(); for (Wave wave : mList) { wave.radius += 5; wave.paint.setStrokeWidth(wave.radius / 3); int alpha = wave.paint.getAlpha(); //如果圆环已经消失, 就需要从集合中移除, 避免OOM if (alpha == 0) { //mList.remove(wave); killedList.add(wave); continue; } alpha -= 8; if (alpha < 0) { alpha = 0; } wave.paint.setAlpha(alpha); } //移除待删除的圆环集合 mList.removeAll(killedList); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: addPoint((int) event.getX(), (int) event.getY()); break; default: break; } return true;//消费事件 } //添加一个触摸点 private void addPoint(int x, int y) { if (mList.isEmpty()) { addWave(x, y); //集合为空, 表示第一次触摸界面, 触发绘制圆环的机制 mHandler.sendEmptyMessageDelayed(0, 50); } else { //确保两个相邻圆环的圆心位置保持一定距离 //取出当前最后一个圆环 Wave lastWave = mList.get(mList.size() - 1); if (Math.abs(lastWave.cx - x) > 10 || Math.abs(lastWave.cy - y) > 10) { addWave(x, y); } } } //添加波浪对象 private void addWave(int x, int y) { Wave wave = new Wave(); wave.cx = x; wave.cy = y; wave.radius = 0; Paint paint = new Paint(); //随机颜色 //Math.random();[0,1); int colorId = (int) (Math.random() * mColors.length); paint.setColor(mColors[colorId]); paint.setStyle(Paint.Style.STROKE);//空心 paint.setAntiAlias(true);//去掉锯齿 paint.setStrokeWidth(radius / 3);//设置圆环宽度, 为半径三分之一 paint.setAlpha(255);//[0..255],设置透明度, 0表示完全透明 wave.paint = paint; mList.add(wave); } @Override protected void onDraw(Canvas canvas) { //绘制圆环 for (Wave wave : mList) { canvas.drawCircle(wave.cx, wave.cy, wave.radius, wave.paint); } } //圆环对象 class Wave { public Paint paint; public int cx; public int cy; public int radius; } }
效果图:
产生一个水波纹的实现
package com.loaderman.mywave; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * 点击屏幕, 产生一个水波纹 */ public class SimpleWave extends View { private Paint paint; private int cx; private int cy; private int radius; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //半径变大 //宽度变大 //颜色变淡 radius += 5; paint.setStrokeWidth(radius / 3); int alpha = paint.getAlpha();//当前透明度 alpha -= 10; if (alpha < 0) { alpha = 0; } paint.setAlpha(alpha); invalidate();//重绘 if (alpha > 0) { //如果圆环没有消失 //继续发送消息, 形成循环 mHandler.sendEmptyMessageDelayed(0, 50); } } }; public SimpleWave(Context context) { this(context, null); } public SimpleWave(Context context, AttributeSet attrs) { this(context, attrs, -1); } public SimpleWave(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE);//空心 paint.setAntiAlias(true);//去掉锯齿 paint.setStrokeWidth(radius / 3);//设置圆环宽度, 为半径三分之一 paint.setAlpha(255);//[0..255],设置透明度, 0表示完全透明 } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //产生一个水波纹 cx = (int) event.getX(); cy = (int) event.getY(); //重新初始化画笔和半径 init(); radius = 0; mHandler.sendEmptyMessageDelayed(0, 50); break; default: break; } return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制圆环: 参1,2: 圆心坐标; 参3:半径 canvas.drawCircle(cx, cy, radius, paint); } }
最后,关注【码上加油站】微信公众号后,有疑惑有问题想加油的小伙伴可以码上加入社群,让我们一起码上加油吧!!!