Android自定义View实现类似水波扩散效果

自定义View一共分为6步

第一步

public SpreadView(Context context) {
    this(context,null,0);
}

public SpreadView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs,0);
}

public SpreadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initPaints();
}

private void initPaints() {

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}

2.实现画笔paint类

本文一共两只画笔

private void initPaints() {
    //画笔1:
    centerPaint = new Paint();
    centerPaint.setColor(Color.YELLOW);
    centerPaint.setAntiAlias(true);//抗锯齿效果
    //最开始不透明且扩散距离为0
    alphas.add(255);
    spreadRadius.add(0);
    //画笔2:
    spreadPaint = new Paint();
    spreadPaint.setAntiAlias(true);
    spreadPaint.setAlpha(255);
    spreadPaint.setColor(Color.RED);
}

3.覆写onMeasure(…)方法

实现这个方法告诉了母容器如何放弃自定义View,可以通过提供的measureSpecs来决定你的View的高和宽,以下是一个正方形,确认它的宽和高是一样的。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int w = MeasureSpec.getSize(widthMeasureSpec);
    int h = MeasureSpec.getSize(heightMeasureSpec);
    int size = Math.min(w, h);
    setMeasuredDimension(size, size);
}

注意:

这个方法需要至少保证一个setMeasuredDimension(..)调用,否则会报IllegalStateException错误。

4.实现onSizeChanged(…)方法

这个方法是你获取View现在的宽和高. 这里我们计算的是中心和半径

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    //圆心位置
    centerX = w / 2;
    centerY = h / 2;
}

5.实现onDraw(…)方法

这个方法提供了如何绘制view,它提供的Canvas类可以进行绘制。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    for (int i = 0; i < spreadRadius.size(); i++) {
        int alpha = alphas.get(i);
        spreadPaint.setAlpha(alpha);
        int width = spreadRadius.get(i);
        //绘制扩散的圆
        canvas.drawCircle(centerX, centerY, radius + width, spreadPaint);
        //每次扩散圆半径递增,圆透明度递减
        if (alpha > 0 && width < 300) {
            alpha = alpha - distance > 0 ? alpha - distance : 1;
            alphas.set(i, alpha);
            spreadRadius.set(i, width + distance);
        }
    }
    //当最外层扩散圆半径达到最大半径时添加新扩散圆
    if (spreadRadius.get(spreadRadius.size() - 1) > maxRadius) {
        spreadRadius.add(0);
        alphas.add(255);
    }
    //超过8个扩散圆,删除最先绘制的圆,即最外层的圆
    if (spreadRadius.size() >= 8) {
        alphas.remove(0);
        spreadRadius.remove(0);
    }
    //中间的圆
    canvas.drawCircle(centerX, centerY, radius, centerPaint);
    //TODO 可以在中间圆绘制文字或者图片
    //延迟更新,达到扩散视觉差效果
    postInvalidateDelayed(delayMilliseconds);
}

6.添加你的View

xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">


            android:id="@+id/spreadView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:spread_center_color="@color/colorAccent"
        app:spread_delay_milliseconds="35"
        app:spread_distance="5"
        app:spread_max_radius="90"
        app:spread_radius="100"
        app:spread_spread_color="@color/colorAccent" />




demo:https://download.csdn.net/download/haoxuhong/10457408

你可能感兴趣的:(Android自定义)