自定义动画水球波纹

自定义动画,水球波纹,因为不知道怎么上传动态图,所以就用静态的了:

自定义控件,重写View

/**
 * 自定义动画水波球
 * Created by IKL on 2018/6/5.
 */

public class WaterWaveProgress extends View {
    // 水的画笔 // 画圆环的画笔// 进度百分比的画笔
    private Paint mPaintWater = null, mRingPaint = null, mTextPaint = null;

    // 圆环颜色 // 圆环背景颜色 // 当前进度 //水波颜色 // 水波背景色 //进度条和水波之间的距离 //进度百分比字体大小
    // //进度百分比字体颜色
    private int mRingColor, mRingBgColor, mWaterColor, mWaterBgColor,
            mFontSize, mTextColor;
    // 进度 //浪峰个数
    float crestCount = 1.5f;
    //描述
    private String s = "";

    float mProgress = 10f, mMaxProgress = 100;

    // 画布中心点
    private Point mCenterPoint;
    // 圆环宽度
    private float mRingWidth, mProgress2WaterWidth;
    // 是否显示进度条 //是否显示进度百分比
    private boolean mShowProgress = false, mShowNumerical = true;

    /**
     * 产生波浪效果的因子
     */
    private long mWaveFactor = 0L;
    /**
     * 正在执行波浪动画
     */
    private boolean isWaving = false;
    /**
     * 振幅
     */
    private float mAmplitude = 10.0F; // 20F
    /**
     * 波浪的速度
     */
    private float mWaveSpeed = 0.040F; // 0.020F
    /**
     * 水的透明度
     */
    private int mWaterAlpha = 255; // 255
    WaterWaveAttrInit attrInit;

    private MyHandler mHandler = null;
    private Paint mDesTextPaint;
    private int mScreenWidth;
    private int mScreenHeight;
    private int mDesFontSize;

    private static class MyHandler extends Handler {
        private WeakReference<WaterWaveProgress> mWeakRef = null;

        private int refreshPeriod = 100;

        public MyHandler(WaterWaveProgress host) {
            mWeakRef = new WeakReference<WaterWaveProgress>(host);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mWeakRef.get() != null) {
                mWeakRef.get().invalidate();
                sendEmptyMessageDelayed(0, refreshPeriod);
            }
        }
    }

    public WaterWaveProgress(Context paramContext) {
        super(paramContext);
    }

    public WaterWaveProgress(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public WaterWaveProgress(Context context, AttributeSet attrs,
                             int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        attrInit = new WaterWaveAttrInit(context, attrs, defStyleAttr);
        init(context);
    }

    @SuppressLint("NewApi")
    private void init(Context context) {
        mCenterPoint = new Point();
        mRingColor = attrInit.getProgressColor();
        mRingBgColor = attrInit.getProgressBgColor();
        mWaterColor = attrInit.getWaterWaveColor();
        mWaterBgColor = attrInit.getWaterWaveBgColor();
        mRingWidth = attrInit.getProgressWidth();
        mProgress2WaterWidth = attrInit.getProgress2WaterWidth();
        mShowProgress = attrInit.isShowProgress();
        mShowNumerical = attrInit.isShowNumerical();
        mFontSize = attrInit.getFontSize();
        mDesFontSize = attrInit.getDesFontSize();
        mTextColor = attrInit.getTextColor();
        mProgress = attrInit.getProgress();
        mMaxProgress = attrInit.getMaxProgress();

        // 如果手机版本在4.0以上,则开启硬件加速
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
            // setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        mRingPaint = new Paint();
        mRingPaint.setAntiAlias(true);
        mRingPaint.setColor(mRingColor); // 圆环颜色
        mRingPaint.setStyle(Paint.Style.STROKE);
        mRingPaint.setStrokeWidth(mRingWidth); // 圆环宽度

        mPaintWater = new Paint();
        mPaintWater.setStrokeWidth(1.0F);
//        mPaintWater.setColor(mWaterColor);
        //设置水的颜色
        mPaintWater.setColor(getResources().getColor(R.color.blue));
        mPaintWater.setAlpha(mWaterAlpha);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(mTextColor);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(mFontSize);

        mDesTextPaint = new Paint();//描述
        mDesTextPaint.setColor(mTextColor);
        mDesTextPaint.setStyle(Paint.Style.FILL);
        mDesTextPaint.setAntiAlias(true);
        mDesTextPaint.setTextSize(mDesFontSize);

        mHandler = new MyHandler(this);

    }

    public void animateWave() {
        if (!isWaving) {
            mWaveFactor = 0L;
            isWaving = true;
            mHandler.sendEmptyMessage(0);
        }
    }

    @SuppressLint({"DrawAllocation", "NewApi"})
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 获取整个View(容器)的宽、高
        int width = getWidth();
        int height = getHeight();
        width = height = (width < height) ? width : height;
        //计算的波峰高度
//        mAmplitude = width / 20f;

        mCenterPoint.x = width / 2;
        mCenterPoint.y = height / 2;
        { // 重新设置进度条的宽度和水波与进度条的距离,,至于为什么写在这,我脑袋抽了可以不
            mRingWidth = mRingWidth == 0 ? width / 20 : mRingWidth;
            mProgress2WaterWidth = mProgress2WaterWidth == 0 ? mRingWidth * 0.6f
                    : mProgress2WaterWidth;
            mRingPaint.setStrokeWidth(mRingWidth);
            mTextPaint.setTextSize(mFontSize == 0 ? width / 5 : mFontSize);
            mDesTextPaint.setTextSize(mDesFontSize == 0 ? width / 5 : mDesFontSize);
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
                setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            } else {
                setLayerType(View.LAYER_TYPE_HARDWARE, null);
            }
        }

        RectF oval = new RectF();
        oval.left = mRingWidth / 2;
        oval.top = mRingWidth / 2;
        oval.right = width - mRingWidth / 2;
        oval.bottom = height - mRingWidth / 2;

        if (isInEditMode()) {
            mRingPaint.setColor(mRingBgColor);
            canvas.drawArc(oval, -90, 360, false, mRingPaint);
            mRingPaint.setColor(mRingColor);
            canvas.drawArc(oval, -90, 90, false, mRingPaint);
            canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mCenterPoint.x
                    - mRingWidth - mProgress2WaterWidth, mPaintWater);
            return;
        }

        // 如果没有执行波浪动画,或者也没有指定容器宽高,就画个简单的矩形
        if ((width == 0) || (height == 0) || isInEditMode()) {
            canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, width / 2
                    - mProgress2WaterWidth - mRingWidth, mPaintWater);
            return;
        }

        // 水与边框的距离
        float waterPadding = mShowProgress ? mRingWidth + mProgress2WaterWidth
                : 0;
        // 水最高处
        int waterHeightCount = mShowProgress ? (int) (height - waterPadding * 2)
                : height;

        // 重新生成波浪的形状
        mWaveFactor++;
        if (mWaveFactor >= Integer.MAX_VALUE) {
            mWaveFactor = 0L;
        }

        // 画进度条背景
        mRingPaint.setColor(mRingBgColor);
        // canvas.drawArc(oval, -90, 360, false, mRingPaint);
        // //和下面效果一样,只不过这个是画个360度的弧,下面是画圆环
        canvas.drawCircle(width / 2, width / 2, waterHeightCount / 2
                + waterPadding - mRingWidth / 2, mRingPaint);
        mRingPaint.setColor(mRingColor);
        // 100为 总进度
        canvas.drawArc(oval, -90, (mProgress * 1f) / mMaxProgress * 360f, false,
                mRingPaint);

        // 计算出水的高度
        float waterHeight = waterHeightCount * (1 - (mProgress * 1f) / mMaxProgress)
                + waterPadding;
        int staticHeight = (int) (waterHeight + mAmplitude);
        Path mPath = new Path();
        mPath.reset();
        if (mShowProgress) {
            mPath.addCircle(width / 2, width / 2, waterHeightCount / 2,
                    Path.Direction.CCW);
        } else {
            mPath.addCircle(width / 2, width / 2, waterHeightCount / 2,
                    Path.Direction.CCW);
        }
        // canvas添加限制,让接下来的绘制都在园内
        canvas.clipPath(mPath, Region.Op.INTERSECT);
//    canvas.clipPath(mPath, Op.REPLACE);
        Paint bgPaint = new Paint();
        bgPaint.setColor(mWaterBgColor);
        // 绘制背景
        canvas.drawRect(waterPadding, waterPadding, waterHeightCount
                + waterPadding, waterHeightCount + waterPadding, bgPaint);
        // 绘制静止的水
        canvas.drawRect(waterPadding, staticHeight, waterHeightCount
                + waterPadding, waterHeightCount + waterPadding, mPaintWater);

        // 待绘制的波浪线的x坐标
        int xToBeDrawed = (int) waterPadding;
        int waveHeight = (int) (waterHeight - mAmplitude
                * Math.sin(Math.PI
                * (2.0F * (xToBeDrawed + (mWaveFactor * width)
                * mWaveSpeed)) / width));
        // 波浪线新的高度
        int newWaveHeight = waveHeight;
        while (true) {
            if (xToBeDrawed >= waterHeightCount + waterPadding) {
                break;
            }
            // 根据当前x值计算波浪线新的高度
            newWaveHeight = (int) (waterHeight - mAmplitude
                    * Math.sin(Math.PI
                    * (crestCount * (xToBeDrawed + (mWaveFactor * waterHeightCount)
                    * mWaveSpeed)) / waterHeightCount));

            // 先画出梯形的顶边
            canvas.drawLine(xToBeDrawed, waveHeight, xToBeDrawed + 1,
                    newWaveHeight, mPaintWater);

            // 画出动态变化的柱子部分
            canvas.drawLine(xToBeDrawed, newWaveHeight, xToBeDrawed + 1,
                    staticHeight, mPaintWater);
            xToBeDrawed++;
            waveHeight = newWaveHeight;
        }
        if (mShowNumerical) {
            String progressTxt = String.format("%.0f", (mProgress * 1f) / mMaxProgress
                    * 100f)
                    + "%";
            float mTxtWidth = mTextPaint.measureText(progressTxt, 0,
                    progressTxt.length());
            canvas.drawText(progressTxt, mCenterPoint.x - mTxtWidth / 2,
                    mCenterPoint.x * 1.5f - mFontSize / 2, mTextPaint);
        }
        //描述
        float left = mDesTextPaint.measureText(s,0,s.length());
        canvas.drawText(s, mScreenWidth * 4 / 8 - left / 2,
                mScreenHeight * 3 / 8, mDesTextPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenWidth = w;
        mScreenHeight = h;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = widthMeasureSpec;
        int height = heightMeasureSpec;
        width = height = (width < height) ? width : height;
        setMeasuredDimension(width, height);
    }

    /**
     * 设置波浪的振幅
     */
    public void setAmplitude(float amplitude) {
        mAmplitude = amplitude;
    }

    /**
     * 设置水的透明度
     *
     * @param alpha 透明的百分比,值为0到1之间的小数,越接近0越透明
     */
    public void setWaterAlpha(float alpha) {
        mWaterAlpha = (int) (255.0F * alpha);
        mPaintWater.setAlpha(mWaterAlpha);
    }

    /**
     * 设置水的颜色
     */
    public void setWaterColor(int color) {
        mWaterColor = color;
    }

    /**
     * 设置当前进度
     */
    public void setProgress(float progress) {
        progress = progress > 100 ? 100 : progress < 0 ? 0 : progress;
        mProgress = progress;
        invalidate();
    }

    /**
     * 获取进度 动画时会用到
     */
    public float getProgress() {
        return mProgress;
    }

    /**
     * 设置波浪速度
     */
    public void setWaveSpeed(float speed) {
        mWaveSpeed = speed;
    }

    /**
     * 是否显示进度条
     *
     * @param b
     */
    public void setShowProgress(boolean b) {
        mShowProgress = b;
    }

    /**
     * 是否显示进度值
     *
     * @param b
     */
    public void setShowNumerical(boolean b) {
        mShowNumerical = b;
    }

    /**
     * 设置进度条前景色
     *
     * @param mRingColor
     */
    public void setmRingColor(int mRingColor) {
        this.mRingColor = mRingColor;
    }

    /**
     * 设置进度条背景色
     *
     * @param mRingBgColor
     */
    public void setmRingBgColor(int mRingBgColor) {
        this.mRingBgColor = mRingBgColor;
    }

    /**
     * 设置水波颜色
     *
     * @param mWaterColor
     */
    public void setmWaterColor(int mWaterColor) {
        this.mWaterColor = mWaterColor;
    }

    /**
     * 设置水波背景色
     *
     * @param mWaterBgColor
     */
    public void setWaterBgColor(int mWaterBgColor) {
        this.mWaterBgColor = mWaterBgColor;
    }

    /**
     * 设置进度值显示字体大小
     *
     * @param mFontSize
     */
    public void setFontSize(int mFontSize) {
        this.mFontSize = mFontSize;
    }

    /**
     * 设置描述显示字体大小
     *
     * @param mDesFontSize
     */
    public void setDesFontSize(int mDesFontSize) {
        this.mDesFontSize = mDesFontSize;
    }

    /**
     * 设置进度值显示字体颜色
     *
     * @param mTextColor
     */
    public void setTextColor(int mTextColor) {
        this.mTextColor = mTextColor;
    }

    /**
     * 设置进度条最大值
     *
     * @param mMaxProgress
     */
    public void setMaxProgress(int mMaxProgress) {
        this.mMaxProgress = mMaxProgress;
    }

    /**
     * 设置浪峰个数
     *
     * @param crestCount
     */
    public void setCrestCount(float crestCount) {
        this.crestCount = crestCount;
    }

    /**
     * 设置进度条宽度
     *
     * @param mRingWidth
     */
    public void setRingWidth(float mRingWidth) {
        this.mRingWidth = mRingWidth;
    }

    /**
     * 设置水波到进度条之间的距离
     *
     * @param mProgress2WaterWidth
     */
    public void setProgress2WaterWidth(float mProgress2WaterWidth) {
        this.mProgress2WaterWidth = mProgress2WaterWidth;
    }

}

设置水波动画

/**
 * 水波动画
 * Created by IKL on 2018/6/5.
 */

public class WaterWaveAttrInit {

    private final int desFontSize;
    private int progressWidth; // 进度条宽度
    private int progressColor;
    private int progressBgColor;
    private int waterWaveColor;
    private int waterWaveBgColor;
    private int progress2WaterWidth; // 进度条和水波之间的间距
    private boolean showProgress; // 是否显示进度条
    private boolean showNumerical; // 是否显示百分比
    private int fontSize;
    private int textColor;
    private int progress;
    private int maxProgress;

    @SuppressLint("Recycle")
    public WaterWaveAttrInit(Context context, AttributeSet attrs, int defStyle) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.WaterWaveProgress, defStyle, 0);
        progressWidth = typedArray.getDimensionPixelOffset(
                R.styleable.WaterWaveProgress_progressWidth, 0);
        progressColor = typedArray.getColor(
                R.styleable.WaterWaveProgress_progressColor, 0xFF33B5E5);
        progressBgColor = typedArray.getColor(
                R.styleable.WaterWaveProgress_progressBgColor, 0xFFBEBEBE);
        waterWaveColor = typedArray.getColor(
                R.styleable.WaterWaveProgress_waterWaveColor, 0XFF4BBDFE);
        waterWaveBgColor = typedArray.getColor(
                R.styleable.WaterWaveProgress_waterWaveBgColor, 0xFFDDDDDD);
        progress2WaterWidth = typedArray.getDimensionPixelOffset(
                R.styleable.WaterWaveProgress_progress2WaterWidth, 0);
        showProgress = typedArray.getBoolean(
                R.styleable.WaterWaveProgress_showProgress, true);
        showNumerical = typedArray.getBoolean(
                R.styleable.WaterWaveProgress_showNumerical, true);
        fontSize = typedArray.getDimensionPixelOffset(
                R.styleable.WaterWaveProgress_fontSize, 0);
        desFontSize = typedArray.getDimensionPixelOffset(
                R.styleable.WaterWaveProgress_desFontSize, 0);
        textColor = typedArray.getColor(
                R.styleable.WaterWaveProgress_textColor, 0xFFFFFFFF);
        progress = typedArray.getInteger(
                R.styleable.WaterWaveProgress_progress, 0);
        maxProgress = typedArray.getInteger(
                R.styleable.WaterWaveProgress_maxProgress, 100);
        typedArray.recycle();
    }

    public int getProgressWidth() {
        return progressWidth;
    }

    public int getProgressColor() {
        return progressColor;
    }

    public int getProgressBgColor() {
        return progressBgColor;
    }

    public int getWaterWaveColor() {
        return waterWaveColor;
    }

    public int getWaterWaveBgColor() {
        return waterWaveBgColor;
    }

    public int getProgress2WaterWidth() {
        return progress2WaterWidth;
    }

    public boolean isShowProgress() {
        return showProgress;
    }

    public boolean isShowNumerical() {
        return showNumerical;
    }

    public int getFontSize() {
        return fontSize;
    }

    public int getDesFontSize() {
        return desFontSize;
    }

    public int getTextColor() {
        return textColor;
    }

    public int getProgress() {
        return progress;
    }

    public int getMaxProgress() {
        return maxProgress;
    }
}

布局中调用

注意!!!!不要复制粘贴!!不要复制粘贴!!不要复制粘贴!!!工程的路径是不一样的!

<qnkj.cn.practice.shuibo.WaterWaveProgress
    android:layout_width="300px"
    android:layout_height="300px"
    android:id="@+id/water_wave_ball_view"
    android:layout_gravity="center_horizontal"
    />
</com.zhy.autolayout.AutoLinearLayout>

找到控件:
WaterWaveProgress waterWaveProgress = findViewById(R.id.water_wave_ball_view);
调用
       //水波动画,传入字符串,表示所占据的百分比大小
        waterWaveProgress.setProgress(Float.parseFloat("71.5"));
        //progress外圈圆形进度条未达到颜色
        waterWaveProgress.setmRingBgColor(getResources().getColor(R.color.light_white));
        //progress,外圈圆形进度条达到颜色
        waterWaveProgress.setmRingColor(getResources().getColor(R.color.blue));
        //球内未到达的颜色
        waterWaveProgress.setWaterBgColor(getResources().getColor(R.color.dark_blue));
        waterWaveProgress.setFontSize(52);
//        waterWaveBallView.setDesFontSize(36);
        waterWaveProgress.setProgress2WaterWidth(1);
        waterWaveProgress.setRingWidth(3);
        //振幅
//        watercircleview.setAmplitude(10f);
//        watercircleview.setWaveSpeed(0.04f);
        waterWaveProgress.setCrestCount(2);
        if (waterWaveProgress.getProgress() != 0) {
            waterWaveProgress.animateWave();//打开波动动画从
        }
        setGrade(waterWaveProgress);

加载水波进度
/**
 * 动画加载水波纹进度
 */
private int mProgress;
public void setGrade(final WaterWaveProgress watercircleview) {
    final float progress = watercircleview.getProgress();
    mProgress = 1;
    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0x1223) {
                watercircleview.setProgress(mProgress * (1));
            } else if (msg.what == 0x1224) {
                watercircleview.setProgress(progress);
            }
        }
    };
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            Message msg = new Message();
            if (mProgress < progress) {
                msg.what = 0x1223;
                mProgress++;
            } else {
                msg.what = 0x1224;
                this.cancel();
            }
            handler.sendMessage(msg);
        }
    }, 0, 25);
}
 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值