博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)水波纹过渡特效
阅读量:4672 次
发布时间:2019-06-09

本文共 5051 字,大约阅读时间需要 16 分钟。

转载地址:

先看效果图:

我们先创建一个UIUtils,转换一些单位:
package com.lgl.test;import android.content.Context;import android.util.DisplayMetrics;import android.view.WindowManager;public class UiUtils {    static public int getScreenWidthPixels(Context context) {        DisplayMetrics dm = new DisplayMetrics();        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()                .getMetrics(dm);        return dm.widthPixels;    }    static public int dipToPx(Context context, int dip) {        return (int) (dip * getScreenDensity(context) + 0.5f);    }    static public float getScreenDensity(Context context) {        try {            DisplayMetrics dm = new DisplayMetrics();            ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()                    .getMetrics(dm);            return dm.density;        } catch (Exception e) {            return DisplayMetrics.DENSITY_DEFAULT;        }    }}
然后写一个WaterRippleView类继承View
package com.lgl.test;import android.content.Context;import android.graphics.Canvas;import android.graphics.DrawFilter;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.PaintFlagsDrawFilter;import android.util.AttributeSet;import android.view.View;public class WaterRippleView extends View {    // 波纹颜色    private static final int WAVE_PAINT_COLOR = 0x880000aa;    // y = Asin(wx+b)+h    private static final float STRETCH_FACTOR_A = 20;    private static final int OFFSET_Y = 0;    // 第一条水波移动速度    private static final int TRANSLATE_X_SPEED_ONE = 7;    // 第二条水波移动速度    private static final int TRANSLATE_X_SPEED_TWO = 5;    private float mCycleFactorW;    private int mTotalWidth, mTotalHeight;    private float[] mYPositions;    private float[] mResetOneYPositions;    private float[] mResetTwoYPositions;    private int mXOffsetSpeedOne;    private int mXOffsetSpeedTwo;    private int mXOneOffset;    private int mXTwoOffset;    private Paint mWavePaint;    private DrawFilter mDrawFilter;    public WaterRippleView(Context context, AttributeSet attrs) {        super(context, attrs);        // 将dp转化为px,用于控制不同分辨率上移动速度基本一致        mXOffsetSpeedOne = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_ONE);        mXOffsetSpeedTwo = UiUtils.dipToPx(context, TRANSLATE_X_SPEED_TWO);        // 初始绘制波纹的画笔        mWavePaint = new Paint();        // 去除画笔锯齿        mWavePaint.setAntiAlias(true);        // 设置风格为实线        mWavePaint.setStyle(Style.FILL);        // 设置画笔颜色        mWavePaint.setColor(WAVE_PAINT_COLOR);        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG                | Paint.FILTER_BITMAP_FLAG);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 从canvas层面去除绘制时锯齿        canvas.setDrawFilter(mDrawFilter);        resetPositonY();        for (int i = 0; i < mTotalWidth; i++) {            // 减400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果            // 绘制第一条水波纹            canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i] - 400, i,                    mTotalHeight, mWavePaint);            // 绘制第二条水波纹            canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - 400, i,                    mTotalHeight, mWavePaint);        }        // 改变两条波纹的移动点        mXOneOffset += mXOffsetSpeedOne;        mXTwoOffset += mXOffsetSpeedTwo;        // 如果已经移动到结尾处,则重头记录        if (mXOneOffset >= mTotalWidth) {            mXOneOffset = 0;        }        if (mXTwoOffset > mTotalWidth) {            mXTwoOffset = 0;        }        // 引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片        postInvalidate();    }    private void resetPositonY() {        // mXOneOffset代表当前第一条水波纹要移动的距离        int yOneInterval = mYPositions.length - mXOneOffset;        // 使用System.arraycopy方式重新填充第一条波纹的数据        System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0,                yOneInterval);        System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval,                mXOneOffset);        int yTwoInterval = mYPositions.length - mXTwoOffset;        System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0,                yTwoInterval);        System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval,                mXTwoOffset);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        // 记录下view的宽高        mTotalWidth = w;        mTotalHeight = h;        // 用于保存原始波纹的y值        mYPositions = new float[mTotalWidth];        // 用于保存波纹一的y值        mResetOneYPositions = new float[mTotalWidth];        // 用于保存波纹二的y值        mResetTwoYPositions = new float[mTotalWidth];        // 将周期定为view总宽度        mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);        // 根据view总宽度得出所有对应的y值        for (int i = 0; i < mTotalWidth; i++) {            mYPositions[i] = (float) (STRETCH_FACTOR_A                    * Math.sin(mCycleFactorW * i) + OFFSET_Y);        }    }}

 

 

然后你就可以绑定在布局上就可以使用了

Demo下载地址:

转载于:https://www.cnblogs.com/zzw1994/p/5198278.html

你可能感兴趣的文章
(5)Oracle基础--约束
查看>>
【Nginx】磁盘文件写入飞地发
查看>>
默认情况下安装的应用程序C盘后提示权限不足,当你开始介意。。。
查看>>
su root 后还是不能使用useradd ,useradd 等命令
查看>>
URL.createObjectURL图片预览
查看>>
js 中exec、test、match、search、replace、split用法
查看>>
Android开发笔记(一)手势识别
查看>>
mybatis 复习笔记03
查看>>
zoj 3703(背包)
查看>>
一种新的子波域滤波算法
查看>>
cookie之三天免登录代码
查看>>
1043 幸运号码 数位DP
查看>>
js18
查看>>
2018-2019-2 20175308实验一 《Java开发环境的熟悉》实验报告
查看>>
如何设置WIN7自动登录(去除登录密码)
查看>>
关于bash中if语法结构的广泛误解(转)
查看>>
10G整数文件中寻找中位数或者第K大数
查看>>
操作手机数据库的uri
查看>>
Python小应用1 - 抓取网页中的链接地址
查看>>
HTML表格和列表笔记&练习<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>关于表格的一些练...
查看>>