自定义view实现水波纹效果(已优化)

引用  http://blog.csdn.NET/tianjian4592/article/details/44222565

看了下网上实现的自定义水波纹效果控件,发现标准正余弦水波纹使用起来很卡顿,因此,实现了一个优化版本:

public class WaveView extends View  
{  
  
	 // 波纹颜色  
    private static final int WAVE_PAINT_COLOR1 = 0x473770dd;  
	 // 波纹颜色  
    private static final int WAVE_PAINT_COLOR2 = 0x333e27f0; 
    
    // y = Asin(wx+b)+h  
    private static final float STRETCH_FACTOR_A = 8;  
    private static final int OFFSET_Y = 0;  
    // 第一条水波移动速度  
    private static final int TRANSLATE_X_SPEED_ONE = 3;  
    // 第二条水波移动速度  
    private static final int TRANSLATE_X_SPEED_TWO = 2;  
    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 mWavePaint1;  
    private Paint mWavePaint2;
    private DrawFilter mDrawFilter;  
    private float progress = 1.0f;
    
    private float nowProgress=0f;
    private int continueTime=0;//上升动画效果持续时间,默认0
    
    /**
     * 
     * @Title: setProgress 
     * @Description: 设置水波纹动画上升的高度百分比及持续时间
     * @author: wukeqi   
     * @date: 2017-4-27 上午8:49:44 
     * @param progress
     * @param continueTime
     * @return: void
     */
    public void setProgress(float progress,int continueTime)
    {
    	this.progress = progress;
    	this.continueTime=continueTime;
    	postInvalidate();
    }
  
    public WaveView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        // 将dp转化为px,用于控制不同分辨率上移动速度基本一致  
        mXOffsetSpeedOne = Utils.dip2px(context, TRANSLATE_X_SPEED_ONE);  
        mXOffsetSpeedTwo =  Utils.dip2px(context, TRANSLATE_X_SPEED_TWO);  
  
        // 初始绘制波纹的画笔  
        mWavePaint1 = new Paint();  
        // 去除画笔锯齿  
        mWavePaint1.setAntiAlias(true);  
        // 设置风格为实线  
        mWavePaint1.setStyle(Style.FILL);  
        // 设置画笔颜色  
        mWavePaint1.setColor(WAVE_PAINT_COLOR1);  
     // 初始绘制波纹的画笔  
        mWavePaint2 = new Paint();  
        // 去除画笔锯齿  
        mWavePaint2.setAntiAlias(true);  
        // 设置风格为实线  
        mWavePaint2.setStyle(Style.FILL);  
        // 设置画笔颜色  
        mWavePaint2.setColor(WAVE_PAINT_COLOR2); 
        
        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] - (mTotalHeight-STRETCH_FACTOR_A)*progress, i,  
                    mTotalHeight,  
                    mWavePaint1);  
  
            // 绘制第二条水波纹  
            canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - (mTotalHeight-STRETCH_FACTOR_A)*progress, i,  
                    mTotalHeight,  
                    mWavePaint2);  
        }  */
        
        canvas.drawLines(mResetOneYPositions, mWavePaint1);
        canvas.drawLines(mResetTwoYPositions, mWavePaint2);
  
        // 改变两条波纹的移动点  
        mXOneOffset += mXOffsetSpeedOne;  
        mXTwoOffset += mXOffsetSpeedTwo;  
  
        // 如果已经移动到结尾处,则重头记录  
        if (mXOneOffset >= mTotalWidth) {  
            mXOneOffset = 0;  
        }  
        if (mXTwoOffset > mTotalWidth) {  
            mXTwoOffset = 0;  
        }  
        
        //y轴上升的 百分比,形成缓缓上升的效果
        nowProgress+=progress/(continueTime/20<=0?1:continueTime/20);
        
        nowProgress=nowProgress>=progress?progress:nowProgress;
  
        // 引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片  
         
        handler.sendEmptyMessageDelayed(0, 20);
    }  
  
    private Handler handler = new Handler()
    		{

				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
					postInvalidate(); 
				}
    	
    		};
    private void resetPositonY() {  
      /*  // mXOneOffset代表当前第一条水波纹要移动的距离  
        int yOneInterval = mYPositions.length/4 - mXOneOffset;  
        // 使用System.arraycopy方式重新填充第一条波纹的数据  
        System.arraycopy(mYPositions, mXOneOffset*4, mResetOneYPositions, 0, yOneInterval*4);  
        System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval*4, mXOneOffset*4);  
        
        
  
        int yTwoInterval = mYPositions.length/4 - mXTwoOffset;  
        System.arraycopy(mYPositions, mXTwoOffset*4, mResetTwoYPositions, 0,  
                yTwoInterval*4);  
        System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval*4, mXTwoOffset*4);*/  
    	
    	//根据偏移量重新赋值(y轴起点处的值)
        
        for(int i=0;i<mTotalWidth;i++){
        	mResetOneYPositions[((mXOneOffset+i)*4+1)%(mTotalWidth*4)]=mYPositions[i*4+1]- (mTotalHeight-STRETCH_FACTOR_A)*nowProgress;
        	mResetTwoYPositions[((mXTwoOffset+i)*4+1)%(mTotalWidth*4)]=mYPositions[i*4+1]- (mTotalHeight-STRETCH_FACTOR_A)*nowProgress;
        }
    }  
  
    @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*4];  
        // 用于保存波纹一的y值  
        mResetOneYPositions = new float[mTotalWidth*4];  
        // 用于保存波纹二的y值  
        mResetTwoYPositions = new float[mTotalWidth*4];  
  
        // 将周期定为view总宽度  
        mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);  
  
        // 根据view总宽度得出所有对应的y值  (4*i+1),并创建drawLines所需要的数组
        for (int i = 0; i < mTotalWidth; i++) { 
        	mYPositions[4*i+0]=i;
        	mYPositions[4*i+1]=(float) (mTotalHeight-(STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y));
        	mYPositions[4*i+2]=i;
            mYPositions[4*i+3] = mTotalHeight;     
        }  
        
        //复制数组
        System.arraycopy(mYPositions, 0, mResetOneYPositions, 0, mTotalWidth*4);  
        System.arraycopy(mYPositions, 0, mResetTwoYPositions, 0, mTotalWidth*4);  
    }
}  

有什么错误的地方希望大家多多指教



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值