我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android如何实现水波纹控件

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android如何实现水波纹控件

小编给大家分享一下Android如何实现水波纹控件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

有很多app使用过水波纹的这样的效果,看着很酷酷的样子,所以自己就撸码写了一个。

Android如何实现水波纹控件

实现思路:

利用贝塞尔曲线绘制圆弧(也就是水波的波纹)
通过动画改变绘制的起始点使水波纹平移

首先,定义我们需要的自定义属性。

<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="waveStyleable">  <!-- 水波纹的长度-->  <attr name="waveLength" format="float"></attr>  <!-- 水波纹的高度-->  <attr name="waveHeight" format="float"></attr>  <!-- 水波纹的速度-->  <attr name="waveSpeed" format="float"></attr>  <!--水波纹上方的头像 -->  <attr name="waveTopIcon" format="reference"></attr>  <!--水波的颜色 -->  <attr name="waveColor" format="color"></attr>  <!--水波距离底部的距离 -->  <attr name="distanceY" format="float"></attr> </declare-styleable></resources>

自定义view绘制水波纹控件

public class WaveView extends View { private Paint paint; private Path path; private float waveLength ; private float waveHeight ; private float waveSpeed ; private Bitmap bitmap; private int waveColor ; private int strokeWidth = 3; private Region region; private int width,height; public int translateX ; private float distanceY; public WaveView(Context context) {  super(context); } public WaveView(Context context, AttributeSet attrs) {  super(context, attrs);  TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.waveStyleable);  waveLength = array.getFloat(R.styleable.waveStyleable_waveLength,300);  waveColor = array.getColor(R.styleable.waveStyleable_waveColor,0x00ff00);  waveHeight = array.getFloat(R.styleable.waveStyleable_waveHeight,100);  waveSpeed = array.getFloat(R.styleable.waveStyleable_waveSpeed,5);  distanceY = array.getFloat(R.styleable.waveStyleable_distanceY,100);  Drawable waveTopICon = array.getDrawable(R.styleable.waveStyleable_waveTopIcon);  array.recycle();  bitmap = drawableToBitmap(waveTopICon);  initPaint();  startAnimal(); } private void initPaint() {  paint = new Paint();  paint.setStyle(Paint.Style.FILL);  paint.setColor(waveColor);  paint.setStrokeWidth(strokeWidth);  //绘制贝塞尔曲线的path  path = new Path(); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  //绘制贝塞尔曲线  drawPath(canvas,path);  //绘制wave上部的头像  drawIcon(canvas); } private void drawIcon(Canvas canvas) {  float baseLine = height-distanceY;  if(region.getBounds().top==baseLine){   canvas.drawBitmap(bitmap,width/2-bitmap.getWidth()/2,region.getBounds().bottom-bitmap.getHeight(),paint);  }else {   if(region.getBounds().top==0){    canvas.drawBitmap(bitmap,width/2-bitmap.getWidth()/2,height-bitmap.getHeight()-distanceY,paint);   }   canvas.drawBitmap(bitmap,width/2-bitmap.getWidth()/2,region.getBounds().top-bitmap.getHeight(),paint);  } } private void drawPath(Canvas canvas, Path path) {  path.reset();  //path的起始点,向手机外多绘制一段  path.moveTo(-2* waveLength +translateX,getHeight()-distanceY);  for(int i = 0; i<getWidth()+ waveLength; i+= waveLength){   path.rQuadTo(waveLength /2,-waveHeight, waveLength,0);   path.rQuadTo(waveLength /2,waveHeight, waveLength,0);  }  region = new Region();  Region clip = new Region();  clip.set((int) (getWidth()/2-0.1),0,getWidth()/2,getHeight()*2);  region.setPath(path,clip);  path.lineTo(getWidth(),getHeight());  path.lineTo(-waveLength,getHeight());  path.close();  canvas.drawPath(path,paint); } public void startAnimal(){  ValueAnimator animator = ValueAnimator.ofFloat(0,1);  animator.setDuration(3000);  animator.setRepeatCount(ValueAnimator.INFINITE);  animator.setInterpolator(new LinearInterpolator());  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @Override   public void onAnimationUpdate(ValueAnimator animation) {    translateX += waveSpeed;    if(-2* waveLength +translateX >= 0){     translateX = 0;    }    postInvalidate();   }  });  animator.start(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  //获取宽高模式  int widthMode = MeasureSpec.getMode(widthMeasureSpec);  int heightMode = MeasureSpec.getMode(heightMeasureSpec);  width = MeasureSpec.getSize(widthMeasureSpec);  height = MeasureSpec.getSize(heightMeasureSpec);  if (widthMode == MeasureSpec.AT_MOST){   width = (int) waveLength;  }  if(heightMode == MeasureSpec.AT_MOST){   height = (int) (waveHeight+ distanceY+bitmap.getHeight());  }  setMeasuredDimension(width,height); }  public float dp2px(float dpValue,Context context){  return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpValue,context.getResources().getDisplayMetrics()); }  public Bitmap makeRoundCorner(Bitmap bitmap) {  int width = bitmap.getWidth();  int height = bitmap.getHeight();  int left = 0, top = 0, right = width, bottom = height;  float roundPx = height/2;  if (width > height) {   left = (width - height)/2;   top = 0;   right = left + height;   bottom = height;  } else if (height > width) {   left = 0;   top = (height - width)/2;   right = width;   bottom = top + width;   roundPx = width/2;  }  Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);  Canvas canvas = new Canvas(output);  int color = 0xff424242;  Paint paint = new Paint();  Rect rect = new Rect(left, top, right, bottom);  RectF rectF = new RectF(rect);  paint.setAntiAlias(true);  canvas.drawARGB(0, 0, 0, 0);  paint.setColor(color);  canvas.drawRoundRect(rectF, roundPx, roundPx, paint);  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.class="lazy" data-src_IN));  canvas.drawBitmap(bitmap, rect, rect, paint);  return output; } public Bitmap drawableToBitmap(Drawable drawable) {  Bitmap bitmap = Bitmap.createBitmap(    drawable.getIntrinsicWidth(),    drawable.getIntrinsicHeight(),    drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888      : Bitmap.Config.RGB_565);  Canvas canvas = new Canvas(bitmap);  drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  drawable.draw(canvas);  return makeRoundCorner(bitmap); }}

相关类:

Path: 可以绘制二次曲线或者三次曲线到画布上,moveTo()方法将path移动到手机屏幕的(-2* waveLength,distanceY)这个点,然后以这个点为起始点绘制二次曲线曲线,rQuadTo(),以最后点为相对位置点进行取点绘制。在属性动画里面,不断改变起始点的位置,这样绘制的水波纹就会平移。

Region:表示区域的类,通过set(path,rect)可以获取到矩形区域与path弧线相交的新的矩形。如果rect的宽度无限小,那么获取的矩形区域会近似为一个点,这个点就是图片移动的y坐标。

xml文件使用:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.iwintrue.waveapplication.MainActivity"> <com.iwintrue.waveapplication.WaveView xmlns:app="http://schemas.android.com/apk/res-auto" app:waveLength = "200" app:waveHeight = "50" app:waveSpeed = "10" app:waveColor = "#0ff" app:distanceY = "100" app:waveTopIcon = "@mipmap/icon" android:layout_centerInParent="true" android:id="@+id/waterView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#f00" /></RelativeLayout>

以上是“Android如何实现水波纹控件”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android如何实现水波纹控件

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android如何实现水波纹控件

小编给大家分享一下Android如何实现水波纹控件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!有很多app使用过水波纹的这样的效果,看着很酷酷的样子,所以自己就
2023-05-30

Android如何实现水波纹效果

这篇文章主要为大家展示了“Android如何实现水波纹效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android如何实现水波纹效果”这篇文章吧。效果图attrs.xml自定义属性
2023-06-29

Android实现水波纹效果

一、效果 点击开始: 点击停止: 二、在MainActivity中import android.graphics.Paint; import android.os.Bundle; import android.support.v4.v
2022-06-06

Android如何实现渐变色水波纹效果

这篇文章主要介绍了Android如何实现渐变色水波纹效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。项目中使用到的效果,效果图如下:代码实现:public class Wa
2023-06-21

Android特效之水波纹的实现

前言 水波纹特效,想必大家或多或少见过,在我的印象中,大致有如下几种: 支付宝 "咻咻咻" 式 流量球 "荡漾" 式 真实的水波纹效果,基于Bitmap处理式话不多说,先来看看效果: 填充式水波纹,间距相等非填充式
2022-06-06

Android实现水波纹点击效果

Android实现水波纹点击效果只在Android5.0以上版本有效,水波纹点击效果代码供大家参考,具体内容如下圆角背景的水波纹效果(如上图) 1. 定义一个普通圆角背景的xml;rounded_corners.xml
2022-06-06

Android实现渐变色水波纹效果

本文实例为大家分享了Android实现渐变色水波纹效果的具体代码,供大家参考,具体内容如下 项目中使用到的效果,效果图如下:代码实现:public class WaveView extends View {private Paint mPa
Android实现渐变色水波纹效果
2022-06-07

Android自定义View实现水波纹效果

介绍:水波纹散开效果的控件在 App 里面还是比较常见的,例如 网易云音乐歌曲识别,附近搜索场景。看下实现的效果:实现思路: 先将最大圆半径与最小圆半径间距分成几等份,从内到外,Paint 透明度依次递减,绘制出同心圆,然后不断的改变这些同
2023-05-30

Android实现点击Button产生水波纹效果

先上图,看看接下来我要向大家介绍的是个什么东西,如下图: 接下来要介绍的就是如何实现上述图中的波纹效果,这种效果如果大家没有体验过的话,可以看看百度手机卫士或者360手机卫士,里面的按钮点击效果都是这样的,另外Android 5.0以上的版
2022-06-06

Android自定义WaveProgressView实现水波纹加载需求

先看效果图:  你可以定义成你项目的logo图片,可以设置水波颜色、波长、波宽、字体大小、颜色、进度条的最大值,当前进度值,还可以设置波纹震动的快慢。当设置一个进度不变的时候,打开时还有一个动画填满的效果(比如第二个流量显示,这里图片没有截
2023-05-30

Android 自定义view实现水波纹动画效果

在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她;在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢;好了
2023-05-31

Android自定义View实现水波纹引导动画

一、实现效果图关于贝塞尔曲线 二、实现代码 1.自定义viewpackage com.czhappy.showintroduce.view; import android.content.Context; import android.gr
2022-06-06

Android实现自定义华丽的水波纹效果

先来看看效果实现效果模拟水波纹的效果:点击屏幕就有圆环出现,半径从小到大,透明度从大到小(0为透明) 实现思路 1.自定义类继承View。 2.定义每个圆环的实体类 Wave,并初始化绘制圆环的画笔的数据。 3
2022-06-06

Android自定义水波纹底部导航的实现

TabLayout作为导航组件来说,使用场景非常的多,也意味着要满足各种各样的需求,这篇文章主要介绍了Android自定义水波纹底部导航的实现
2022-11-13

Android自定义view实现水波纹进度球效果

今天我们要实现的这个view没有太多交互性的view,所以就继承view。 自定义view的套路,套路很深 1、获取我们自定义属性attrs(可省略) 2、重写onMeasure方法,计算控件的宽和高 3、重
2022-06-06

Android自定义View 实现水波纹动画引导效果

一、实现效果图二、实现代码 1.自定义viewpackage com.czhappy.showintroduce.view; import android.content.Context; import android.graphics.B
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录