开发中的东西太多,怕自己忘记了,简单记录一下。
声明:此控件借鉴了大佬的想法,在此感谢大佬提供的支持,我只是把大佬的想法拿出来而已。
ok,废话到此结束,看效果:
分析一下,我们可以看到,图中有两个圆:stop状态下,黄色的默认图,start状态下,水波纹效果的黑色的圆,默认状态下下的圆没什么好说的,直接通过
canvas.drawCircle绘制一个圆就好,关键是,点击start之后,黑色的圆的水波纹怎么搞。我们可以观察这个水波纹,他是由好多个透明度同的圆来组成的,我们就可以在绘制这个黑色的圆的时候,通过设定他的半径和透明度的方式来实现这样一个效果。
下面还是上代码吧,再下去,我自己都晕了
public class WaterRippleView extends android.support.v7.widget.AppCompatTextView { /** * 波纹生成时的半径 */ private float mWaveRadiusMin; /** * 波纹消失前的半径 */ private float mWaveRadiusMax; /** * 每条波纹持续时间 */ private long mWaveDuration; private Paint mPaint; /** * 中间圆圈的画笔 */ private Paint mCenterCirclePaint; /** * 画笔是否为stroke模式(即线条) */ private boolean stroke = false; /** * 波纹颜色 */ private int mWaveColor; /** * 波纹停止的颜色 */ private int mWaveStopColor; /** * 波纹动画效果 */ private Interpolator mInterpolator = new DecelerateInterpolator(); private boolean mIsRunning; private int mStopCircleColor; private int mCenterCircleRadius; /** * 动画集合 */ private ArrayList<ValueAnimator> mAnimators; public WaterRippleView(Context context) { this(context, null); } public WaterRippleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public WaterRippleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //执行初始化 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.WaterRippleView, 0, defStyleAttr); mWaveColor = typedArray.getColor(R.styleable.WaterRippleView_color, Color.BLUE); mStopCircleColor = getResources().getColor(R.color.income_top);//设置停止状态下的颜色--默认值 mWaveStopColor = typedArray.getColor(R.styleable.WaterRippleView_stopColor, Color.BLUE);//设置停止状态下的额颜色--xml mWaveDuration = typedArray.getInteger(R.styleable.WaterRippleView_duration, 3000); stroke = typedArray.getBoolean(R.styleable.WaterRippleView_stroke, false);//是否开启水波纹效果 typedArray.recycle();//释放掉TypedArray mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置抗锯齿 mPaint.setDither(true); mPaint.setStrokeWidth(3);//设置线的粗细 mAnimators = new ArrayList<>(); mCenterCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCenterCirclePaint.setStyle(Paint.Style.FILL); mCenterCirclePaint.setColor(mStopCircleColor); if (stroke) { mPaint.setStyle(Paint.Style.STROKE); } else { mPaint.setStyle(Paint.Style.FILL); } } private ValueAnimator createAnimator() { ValueAnimator animator = new ValueAnimator(); animator.setFloatValues(mWaveRadiusMin, mWaveRadiusMax); L.d("mWaveRadiusMin", mWaveRadiusMin + ""); L.d("mWaveRadiusMax", mWaveRadiusMax + ""); animator.setDuration(mWaveDuration); animator.setRepeatCount(-1); animator.setInterpolator(mInterpolator); return animator; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); mCenterCircleRadius = (int) (size / 2 * 0.8); mWaveRadiusMin = mCenterCircleRadius; mWaveRadiusMax = size / 2; } @Override protected void onDraw(Canvas canvas) { int cX = getMeasuredWidth() / 2; int cY = getMeasuredHeight() / 2; if (mIsRunning) { if (mAnimators.size() > 0) { for (ValueAnimator mAnimator : mAnimators) { if (mAnimator != null) { float animatorValue = (float) mAnimator.getAnimatedValue(); L.d("animatorValue", "" + animatorValue); //设置透明度 int alpha = getAlpha(animatorValue); mPaint.setAlpha(alpha); //画水波纹 canvas.drawCircle(cX, cY, animatorValue, mPaint); } } } } canvas.drawCircle(cX, cY, mCenterCircleRadius, mCenterCirclePaint); postInvalidate(); super.onDraw(canvas); } private void createAnimators() { for (int i = 0; i < 3; i++) { mAnimators.add(createAnimator()); } } //开启动画 public void start() { if (mIsRunning) { return; } mIsRunning = true; mPaint.setColor(mWaveColor); mCenterCirclePaint.setColor(mWaveColor); if (mAnimators.size() == 0) { createAnimators(); } final int size = mAnimators.size(); for (int i = 0; i < size; i++) { final int index = i; postDelayed(new Runnable() { @Override public void run() { if (mIsRunning && index < size) { mAnimators.get(index).start(); } } }, (long) (mWaveDuration * index * 1f / size)); } postInvalidate(); } //是否开启水波纹 public boolean isStart() { for (ValueAnimator mAnimator : mAnimators) { if (mAnimator == null && !mAnimator.isRunning()) { return false; } } return true; } //关闭动画 public void stop() { mIsRunning = false; mPaint.setColor(mStopCircleColor); mCenterCirclePaint.setColor(mStopCircleColor); for (ValueAnimator mAnimator : mAnimators) { if (mAnimator != null) { mAnimator.cancel(); } } mAnimators.clear(); } //设置水波纹颜色 public void setColor(int color) { mWaveColor = color; postInvalidate(); } //设计水波纹持续时间 public void setDuration(long duration) { mWaveDuration = duration; postInvalidate(); } //是否画笔stroke public void setStroke(boolean stroke) { this.stroke = stroke; postInvalidate(); } public boolean isStroke() { return stroke; } //获取水波纹透明度 private int getAlpha(float mRadius) { int alpha = 1; if (mWaveRadiusMax > 0) { alpha = (int) ((1 - (mRadius - mWaveRadiusMin) / (mWaveRadiusMax - mWaveRadiusMin)) * 127); } return alpha; } }XML中引用:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text="start" /> <Button android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text="stop" /> <com.zhd.admin.androldlrden.view.WaterRippleView android:id="@+id/wrv_water" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" app:color="@color/dig_wave" app:duration="1500" app:stopColor="#00000000" app:stroke="false" app:waveCreateSpeed="500" /></LinearLayout>Activity中使用:
public class MainActivity extends AppCompatActivity { private WaterRippleView waterRippleView; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); waterRippleView = findViewById(R.id.wrv_water); textView = findViewById(R.id.click); } public void onClick(View view) { switch (view.getId()) { case R.id.click: waterRippleView.setStroke(true); waterRippleView.start(); break; case R.id.stop: waterRippleView.stop(); break; } } }ok,这样就可以了。
PS:第一次写这种东西,说的不是很清楚,欢迎大家补充,以后会不定期记录自己学到的东西。
-------------------------羞耻的分割线-------------------------------更新一下项目地址 https://github.com/zhddream/WaterRippleView
转载于:https://www.cnblogs.com/zhdsky/p/8892272.html
相关资源:Android自定义View控件实现多种水波纹涟漪扩散效果