zoukankan      html  css  js  c++  java
  • (转)水波纹过渡特效

    转载地址:http://blog.csdn.net/qq_26787115/article/details/50439020

    先看效果图:

    我们先创建一个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);
            }
        }
    
    }
    <com.lgl.test.WaterRippleView
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       />
    然后你就可以绑定在布局上就可以使用了

    Demo下载地址:http://download.csdn.net/detail/qq_26787115/9384803

  • 相关阅读:
    IIS浏览显示目录
    图解NuGet的安装和使用
    未能找到类型或命名空间名称“DbContext”
    IIS报错:未将对象引用设置到对象的实例
    最新11位手机号正则表达式
    Sql Server连表查询字段为null
    sql server 表连接
    2019用卡提额攻略
    win10,7 80端口被占用的检测和解决方法
    SAP之RFC_READ_TABLE
  • 原文地址:https://www.cnblogs.com/zzw1994/p/5198278.html
Copyright © 2011-2022 走看看