自定义view实现水波纹效果.docx
《自定义view实现水波纹效果.docx》由会员分享,可在线阅读,更多相关《自定义view实现水波纹效果.docx(21页珍藏版)》请在冰豆网上搜索。
![自定义view实现水波纹效果.docx](https://file1.bdocx.com/fileroot1/2022-11/15/32a6c0a2-3529-4069-bfab-1e54618822e2/32a6c0a2-3529-4069-bfab-1e54618822e21.gif)
自定义view实现水波纹效果
自定义view实现水波纹效果
我先们来学习效果1:
效果1实现本质:
用一张波形图和一个圆形图的图片,然后圆形图在波形图上方,然后使用安卓的图片遮罩模式desIn(不懂?
那么先记住有这样一个遮罩模式).(只显示上部图像和下部图像公共部分的下半部分),是不是很难懂?
那么我在说清一点并且配图.假设圆形图在波形图上面,那么只会显示两者相交部分的波形图
下面是解释效果图(正方形蓝色图片在黄色圆形上面):
这次的实现我们都选择继承view,在实现的过程中我们需要关注如下几个方法:
1.onMeasure():
最先回调,用于控件的测量;
2.onSizeChanged():
在onMeasure后面回调,可以拿到view的宽高等数据,在横竖屏切换时也会回调;
3.onDraw():
真正的绘制部分,绘制的代码都写到这里面;
先来看看我们定义的变量:
//波形图
BitmapwaveBitmap;
//圆形遮罩图
BitmapcircleBitmap;
//波形图src
RectwaveSrcRect;
//波形图dst
RectwaveDstRect;
//圆形遮罩src
RectcircleSrcRect;
//圆形遮罩dst
RectcircleDstRect;
//画笔
Paintmpaint;
//图片遮罩模式
PorterDuffXfermodemode;
//控件的宽
intviewWidth;
//控件的高
intviewHeight;
//图片过滤器
PaintFlagsDrawFilterpaintFlagsDrawFilter;
//每次移动的距离
intspeek=10;
//当前移动距离
intnowOffSet;
介绍一个方法:
voidandroid.graphics.Canvas.drawBitmap(Bitmapbitmap,Rectsrc,Rectdst,Paintpaint)
1
1
此方法的参数:
参数1:
你的图片
参数2:
矩形.也就是说此矩形决定你画出图片参数1的哪个位置,比如说你的矩形是设定是Rectrect=newRect(0,0,图片宽,图片高)那么将会画出图片全部
参数3:
矩形.决定你图片缩放比例和在view中的位置.假设你的矩形Rectrect=newRect(0,0,100,100)那么你将在自定义view中(0,0)点到(100,100)绘画此图片并且如果图片大于(小于)此矩形那么按比例缩小(放大)
来看看初始化方法
//初始化
privatevoidinit(){
mpaint=newPaint();
//处理图片抖动
mpaint.setDither(true);
//抗锯齿
mpaint.setAntiAlias(true);
//设置图片过滤波
mpaint.setFilterBitmap(true);
//设置图片遮罩模式
mode=newPorterDuffXfermode(PorterDuff.Mode.DST_IN);
//给画布直接设定参数
paintFlagsDrawFilter=newPaintFlagsDrawFilter(0,Paint.DITHER_FLAG|Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
//初始化图片
//使用drawable获取的方式,全局只会生成一份,并且系统会进行管理,
//而BitmapFactory.decode()出来的则decode多少次生成多少张,务必自己进行recycle;
//获取波形图
waveBitmap=((BitmapDrawable)getResources().getDrawable(R.drawable.wave_2000)).getBitmap();
//获取圆形遮罩图
circleBitmap=((BitmapDrawable)getResources().getDrawable(R.drawable.circle_500)).getBitmap();
//不断刷新波形图距离读者可以先不看这部分内容因为需要结合其他方法
newThread(){
publicvoidrun(){
while(true){
try{
//移动波形图
nowOffSet=nowOffSet+speek;
//如果移动波形图的末尾那么重新来
if(nowOffSet>=waveBitmap.getWidth()){
nowOffSet=0;
}
sleep(30);
postInvalidate();
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
};
}.start();
}
以下获取view的宽高并设置对应的波形图和圆形图矩形(会在onMesure回调后执行)
@Override
protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
super.onSizeChanged(w,h,oldw,oldh);
//获取view宽高
viewWidth=w;
viewHeight=h;
//波形图的矩阵初始化
waveSrcRect=newRect();
waveDstRect=newRect(0,0,w,h);
//圆球矩阵初始化
circleSrcRect=newRect(0,0,circleBitmap.getWidth(),circleBitmap.getHeight());
circleDstRect=newRect(0,0,viewWidth,viewHeight);
}
那么最后来看看绘画部分吧
@Override
protectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);
//给图片直接设置过滤效果
canvas.setDrawFilter(paintFlagsDrawFilter);
//给图片上色
canvas.drawColor(Color.TRANSPARENT);
//添加图层注意!
!
!
!
!
使用图片遮罩模式会影响全部此图层(也就是说在canvas.restoreToCount所有图都会受到影响)
intsaveLayer=canvas.saveLayer(0,0,viewWidth,viewHeight,null,Canvas.ALL_SAVE_FLAG);
//画波形图部分矩形
waveSrcRect.set(nowOffSet,0,nowOffSet+viewWidth/2,viewHeight);
//画矩形
canvas.drawBitmap(waveBitmap,waveSrcRect,waveDstRect,mpaint);
//设置图片遮罩模式
mpaint.setXfermode(mode);
//画遮罩
canvas.drawBitmap(circleBitmap,circleSrcRect,circleDstRect,mpaint);
//还原画笔模式
mpaint.setXfermode(null);
//将图层放上
canvas.restoreToCount(saveLayer);
}
最后看下完整的代码
packagecom.fmy.shuibo1;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.PaintFlagsDrawFilter;
importandroid.graphics.PorterDuff;
importandroid.graphics.PorterDuffXfermode;
importandroid.graphics.Rect;
importandroid.graphics.drawable.BitmapDrawable;
importandroid.icu.text.TimeZoneFormat.ParseOption;
importandroid.util.AttributeSet;
importandroid.view.View;
publicclassMySinUiextendsView{
//波形图
BitmapwaveBitmap;
//圆形遮罩图
BitmapcircleBitmap;
//波形图src
RectwaveSrcRect;
//波形图dst
RectwaveDstRect;
//圆形遮罩src
RectcircleSrcRect;
//圆形遮罩dst
RectcircleDstRect;
//画笔
Paintmpaint;
//图片遮罩模式
PorterDuffXfermodemode;
//控件的宽
intviewWidth;
//控件的高
intviewHeight;
//图片过滤器
PaintFlagsDrawFilterpaintFlagsDrawFilter;
//每次移动的距离
intspeek=10;
//当前移动距离
intnowOffSet;
publicMySinUi(Contextcontext,AttributeSetattrs){
super(context,attrs);
init();
}
//初始化
privatevoidinit(){
mpaint=newPaint();
//处理图片抖动
mpaint.setDither(true);
//抗锯齿
mpaint.setAntiAlias(true);
//设置图片过滤波
mpaint.setFilterBitmap(true);
//设置图片遮罩模式
mode=newPorterDuffXfermode(PorterDuff.Mode.DST_IN);
//给画布直接设定参数
paintFlagsDrawFilter=newPaintFlagsDrawFilter(0,Paint.DITHER_FLAG|Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
//初始化图片
//使用drawable获取的方式,全局只会生成一份,并且系统会进行管理,
//而BitmapFactory.decode()出来的则decode多少次生成多少张,务必自己进行recycle;
/