水波纹png-如何给Imageview设置水波纹效果

如题所述

如何给Imageview设置水波纹效果

水波纹效果:

1.标准正余弦水波纹;

2.非标准圆形液柱水波纹;

虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余弦函数模拟水波纹效果,另外一个会运用到图像的混合模式(PorterDuffXfermode);

先看效果:

自定义View根据实际情况可以选择继承自View、TextView、ImageView或其他

这次的实现我们都选择继承view,在实现的过程中我们需要关注如下几个方法:

1.onMeasure():最先回调,用于控件的测量;

2.onSizeChanged():在onMeasure后面回调,可以拿到view的宽高等数据,在横竖屏切换时也会回调;

3.onDraw():真正的绘制部分,绘制的代码都写到这里面;

既然如此,我们先复写这三个方法,然后来实现如上两个效果;

一:标准正余弦水波纹

这种水波纹可以用具体函数模拟出具体的轨迹,所以思路基本如下:

1.确定水波函数方程

2.根据函数方程得出每一个波纹上点的坐标;

3.将水波进行平移,即将水波上的点不断的移动;

4.不断的重新绘制,生成动态水波纹;

有了上面的思路,我们一步一步进行实现:

正余弦函数方程为:

y=_sin(wx+b)+h,这个公式里:w影响周期,A影响振幅,h影响y位置,b为初相;

根据上面的方程选取自己觉得中意的波纹效果,确定对应参数的取值;

然后根据确定好的方程得出所有的方程上y的数值,并将所有y值保存在数组里:

//_芷诙ㄎ_iew总宽度_

mCycleFactorW=(float)(2*_/_TotalWidth);_

//__iew总宽度得出所有对应的y值_

for(int_=0;_<_TotalWidth;_++)__

__mYPositions[i]=(float)(STRETCH_FACTOR_A*(mCycleFactorW*_)+_FFSET_Y);_

}_

根据得出的所有y值,则可以在onDraw中通过如下代码绘制两条静态波纹:

for(int_=0;_<_TotalWidth;_++)__

___//_400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果_

___//_嬷频谝惶跛ㄎ_

___(i,_TotalHeight-_ResetOneYPositions[i]-400,_,_

_______mTotalHeight,_

_______mWavePaint);_

___//_嬷频诙跛ㄎ_

___(i,_TotalHeight-_ResetTwoYPositions[i]-400,_,_

_______mTotalHeight,_

_______mWavePaint);_

_}_

这种方式类似于数学里面的细分法,一条波纹,如果横向以一个像素点为单位进行细分,则形成view总宽度条直线,并且每条直线的起点和终点我们都能知道,在此基础上我们只需要循环绘制出所有细分出来的直线(直线都是纵向的),则形成了一条静态的水波纹;

接下来我们让水波纹动起来,之前用了一个数组保存了所有的y值点,有两条水波纹,再利用两个同样大小的数组来保存两条波纹的y值数据,并不断的去改变这两个数组中的数据:

_rivate_oid_esetPositonY()__

__//_XOneOffset代表当前第一条水波纹要移动的距离_

__int_OneInterval=_-_XOneOffset;_

__//_褂梅绞街匦绿畛涞谝惶醪ㄎ频氖_

__(mYPositions,_XOneOffset,_ResetOneYPositions,0,_OneInterval);_

__(mYPositions,0,_ResetOneYPositions,_OneInterval,_XOneOffset);_

__int_TwoInterval=_-_XTwoOffset;_

__(mYPositions,_XTwoOffset,_ResetTwoYPositions,0,_

______yTwoInterval);_

__(mYPositions,0,_ResetTwoYPositions,_TwoInterval,_XTwoOffset);_

}_

如此下来只要不断的改变这两个数组的数据,然后不断刷新,即可生成动态水波纹了;

刷新可以调用invalidate()或postInvalidate(),区别在于后者可以在子线程中更新UI

整体代码如下:

package;

import;

import;

import;

import;

import;

import;

import;

import;

import;

public_lass_ynamicWave_xtends_iew_

__//_ㄎ蒲丈

__private_tatic_inal_nt_AVE_PAINT_COLOR=0x880000aa;

__//_=_sin(wx+b)+h

__private_tatic_inal_loat_TRETCH_FACTOR_A=20;

__private_tatic_inal_nt_FFSET_Y=0;

__//_谝惶跛ㄒ贫俣

__private_tatic_inal_nt_RANSLATE_X_SPEED_ONE=7;

__//_诙跛ㄒ贫俣

__private_tatic_inal_nt_RANSLATE_X_SPEED_TWO=5;

__private_loat_CycleFactorW;

__private_nt_TotalWidth,_TotalHeight;

__private_loat[]_YPositions;

__private_loat[]_ResetOneYPositions;

__private_loat[]_ResetTwoYPositions;

__private_nt_XOffsetSpeedOne;

__private_nt_XOffsetSpeedTwo;

__private_nt_XOneOffset;

__private_nt_XTwoOffset;

__private_aint_WavePaint;

__private_rawFilter_DrawFilter;

__public_ynamicWave(Context_ontext,_ttributeSet_ttrs)_

____super(context,_ttrs);

____//__p转化为px,用于控制不同分辨率上移动速度基本一致

____mXOffsetSpeedOne=(context,_RANSLATE_X_SPEED_ONE);

____mXOffsetSpeedTwo=(context,_RANSLATE_X_SPEED_TWO);

____//_跏蓟嬷撇ㄎ频幕

____mWavePaint=_ew_aint();

____//_コ示獬

____(true);

____//_柚梅绺裎迪

____();

____//_柚没恃丈

____(WAVE_PAINT_COLOR);

____mDrawFilter=_ew_aintFlagsDrawFilter(0,_ALIAS_FLAG__BITMAP_FLAG);

__}

__@Override

__protected_oid_nDraw(Canvas_anvas)_

____(canvas);

____//__anvas层面去除绘制时锯齿

____(mDrawFilter);

____resetPositonY();

____for(int_=0;_<_TotalWidth;_++)_

______//_400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果

______//_嬷频谝惶跛ㄎ

______(i,_TotalHeight-_ResetOneYPositions[i]-400,_,

__________mTotalHeight,

__________mWavePaint);

______//_嬷频诙跛ㄎ

______(i,_TotalHeight-_ResetTwoYPositions[i]-400,_,

__________mTotalHeight,

__________mWavePaint);

____}

____//_谋淞教醪ㄎ频囊贫

____mXOneOffset+=_XOffsetSpeedOne;

____mXTwoOffset+=_XOffsetSpeedTwo;

____//_绻丫贫浇嵛泊,则重头记录

____if(mXOneOffset>=_TotalWidth)_

______mXOneOffset=0;

____}

____if(mXTwoOffset>_TotalWidth)_

______mXTwoOffset=0;

____}

____//_view重绘,一般可以考虑延迟20-30ms重绘,空出时间片

____postInvalidate();

__}

__private_oid_esetPositonY()_

____//_XOneOffset代表当前第一条水波纹要移动的距离

____int_OneInterval=_-_XOneOffset;

____//_褂梅绞街匦绿畛涞谝惶醪ㄎ频氖

____(mYPositions,_XOneOffset,_ResetOneYPositions,0,_OneInterval);

____(mYPositions,0,_ResetOneYPositions,_OneInterval,_XOneOffset);

____int_TwoInterval=_-_XTwoOffset;

____(mYPositions,_XTwoOffset,_ResetTwoYPositions,0,

________yTwoInterval);

____(mYPositions,0,_ResetTwoYPositions,_TwoInterval,_XTwoOffset);

__}

__@Override

__protected_oid_nSizeChanged(int_,_nt_,_nt_ldw,_nt_ldh)_

____(w,_,_ldw,_ldh);

____//_锹枷_iew的宽高

____mTotalWidth=_;

____mTotalHeight=_;

____//_糜诒4嬖疾ㄎ频_值

____mYPositions=_ew_loat[mTotalWidth];

____//_糜诒4娌ㄎ埔坏_值

____mResetOneYPositions=_ew_loat[mTotalWidth];

____//_糜诒4娌ㄎ贫_值

____mResetTwoYPositions=_ew_loat[mTotalWidth];

____//_芷诙ㄎ_iew总宽度

____mCycleFactorW=(float)(2*_/_TotalWidth);

____//__iew总宽度得出所有对应的y值

____for(int_=0;_<_TotalWidth;_++)_

______mYPositions[i]=(float)(STRETCH_FACTOR_A*(mCycleFactorW*_)+_FFSET_Y);

____}

__}

}

二:非标准圆形液柱水波纹

前面的波形使用函数模拟,这个我们换种方式,采用图进行实现,先用PS整张不像波纹的波纹图;

为了衔接紧密,首尾都比较平,并高度一致;

思路:

1.使用一个圆形图作为遮罩过滤波形图;

2.平移波纹图,即不断改变绘制的波纹图的区域,即srcRect;

3.当一个周期绘制完,则从波纹图的最前面重新计算;_

全部代码如下

__//_跏蓟_itmap

__private_oid_nitBitmap()_

____mSrcBitmap=((BitmapDrawable)

________.getBitmap();

____mMaskBitmap=((BitmapDrawable)_etResources().getDrawable(

________R._500))

________.getBitmap();

__}

__//_跏蓟_aint

__private_oid_nitPaint()_

____mBitmapPaint=_ew_aint();

____//_蓝抖

____(true);

____//_敉枷窆

____(true);

____mPicPaint=_ew_aint(_ALIAS_FLAG);

____(true);

____();

__}

__@Override

__protected_oid_nSizeChanged(int_,_nt_,_nt_ldw,_nt_ldh)_

____(w,_,_ldw,_ldh);

____mTotalWidth=_;

____mTotalHeight=_;

____mCenterX=_TotalWidth/2;

____mCenterY=_TotalHeight/2;

____mSrcRect=_ew_ect();

____mDestRect=_ew_ect(0,0,_TotalWidth,_TotalHeight);

____int_askWidth=();

____int_askHeight=();

____mMaskSrcRect=_ew_ect(0,0,_askWidth,_askHeight);

____mMaskDestRect=_ew_ect(0,0,_TotalWidth,_TotalHeight);

__}

}

如何给Imageview设置水波纹效果

假设图片名是myImage@用[buttonSetBackgroundImage:[UIImageimageNamed:@"myImage"]];就可以了。多少个button公用一张图片都是可以的,不会出现冲突问题,系统会根据这个图片生成N个实例对象。

温馨提示:答案为网友推荐,仅供参考