android实现波纹效果


前几天公司需要做录音的波纹效果,原理很简单:定义一个记录所有同心圆半径的list,只要动态改变list的size,然后遍历之,并以每一个半径绘制圆(drawCircle), 通过在onDraw方法里面不停invalidate就可以了,代码如下:

package com.example.test.util;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

import com.example.test.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jisj on 6/1/16.
 */
public class RecordView extends View {
    public RecordView(Context context) {
        this(context, null, 0);
    }

    public RecordView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecordView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    public void setIsWaving(boolean waving){
        isWaving = waving;
        postInvalidate();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.parseColor("#ff6666"));
        paint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(width = 600, height = 600);
        initOtherSize();
        initStartCircle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int count = radiusList.size();
        //先绘制波纹
        if(isWaving){
            for (int i = 0; i < count; i++) {
                int radius = radiusList.get(i);
                float alpha = alphaList.get(i);
                paint.setAlpha((int) alpha);
                canvas.drawCircle(width / 2, height / 2, radius, paint);
                //宽度递增,透明度递减,宽度到最大时,透明度正好为0,singleAlpha保证了最外层的圆消失时不会突兀
                if (alpha - singleAlpha >= 0)
                    alphaList.set(i, alpha - singleAlpha);
                if (radius + 1 < this.width / 2) {
                    radiusList.set(i, radius + 1);
                }
            }
        }

        //再绘制中间的图片
        Drawable drawable = context.getResources().getDrawable(R.drawable.center_pic);
        drawable.setBounds((width - centerWidth) / 2, (height - centerWidth) / 2, (width + centerWidth) / 2, (height + centerWidth) / 2);
        drawable.draw(canvas);
        if(isWaving){
            //如果没有达到最多的圆数,则加一个最内层的圆
            if (count <= MAX_CIRCLE_COUNT) {
                //这里的width / (MAX_CIRCLE_COUNT * 7)是相邻波纹的半径差值
                if (radiusList.size() <= 0 || radiusList.get(radiusList.size() - 1) == centerWidth / 2 + width / (MAX_CIRCLE_COUNT * 7)) {
                    addInnerCircle();
                }
            }
            //去掉最外层的圆
            if (radiusList.size() > MAX_CIRCLE_COUNT) {
                radiusList.remove(0);
                alphaList.remove(0);
            }
            //执行onDraw的不断循环
            postInvalidate();
        }
    }


    private void initStartCircle() {
        clearDataList(alphaList);
        clearDataList(radiusList);
        alphaList.add(ORIGIN_ALPHA);
        radiusList.add(startRadius);
    }

    private void initOtherSize() {
        centerWidth = (int) (width * 0.54f);
        //startRadius比centerWidth略小,是为了保证起始圆环出场时藏在中心图片下面,不然会太突然
        startRadius = centerWidth / 2 - 30;
        //圆环每增加1个像素,则透明度减低的值
        singleAlpha = ORIGIN_ALPHA / ((width / 2 - startRadius));
    }

    private void addInnerCircle() {
        alphaList.add(ORIGIN_ALPHA);
        radiusList.add(startRadius);
    }

    private void clearDataList(List list) {
        if (list.size() > 0)
            list.clear();
    }

    private ArrayList<Float> alphaList = new ArrayList<Float>();
    private ArrayList<Integer> radiusList = new ArrayList<Integer>();

    private int width, height;
    private float singleAlpha = 1;                      //圆环每增加1个像素,则透明度减低的值
    private int centerWidth;                            //中间固定图片的半径
    private int startRadius;                            //起始圆环的半径
    private boolean isWaving = false;
    private Paint paint;
    private Context context;

    private static final float ORIGIN_ALPHA = 150;      //最内层圆环的透明度
    private static final int MAX_CIRCLE_COUNT = 5;      //最多的圆环数量

}


代码中用到的图片,是百度搜到的,如果有侵权。。。。。对不起啊大哥


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值