Android项目实战手把手教你画圆形水波纹loadingview

作者:菜鸡wing 时间:2023-03-15 10:13:47 

本文实例讲解的是如何画一个满满圆形水波纹loadingview,这类效果应用场景很多,比如内存占用百分比之类的,分享给大家供大家参考,具体内容如下

效果图如下:

Android项目实战手把手教你画圆形水波纹loadingview

预备的知识:

  • 1.贝塞尔曲线    如果你不了解,可以来这里进行基础知识储备:神奇的贝塞尔曲线
       

  • 2.Paint.setXfermode()以及PorterDuffXfermode

千万不要被这个b的名字吓到,不熟悉看到可能会认为很难记,其实 只要站在巨人的丁丁上 还是很简单的。
好了 废话不多说 ,跟我一步步来做一个炫酷的view吧。

首先给一些属性,在构造器里初始化(不要再ondraw new东西不要再ondraw new东西不要再ondraw new东西不要再ondraw new东西)


 //绘制波纹
 private Paint mWavePaint;  
 private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//设置mode 为XOR
 //绘制圆
 private Paint mCirclePaint;
 private Canvas mCanvas;//我们自己的画布
 private Bitmap mBitmap;
 private int mWidth;
 private int mHeight;

public WaveLoadingView(Context context) {
   this(context,null);
 }

public WaveLoadingView(Context context, AttributeSet attrs) {
   this(context, attrs,0);
 }

public WaveLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);

mWavePaint = new Paint();
   mWavePaint.setColor(Color.parseColor("#33b5e5"));
   mCirclePaint = new Paint();
   mCirclePaint.setColor(Color.parseColor("#99cc00"));

}
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   int widthSize = MeasureSpec.getSize(widthMeasureSpec);
   int widthMode = MeasureSpec.getMode(widthMeasureSpec);
   int heightSize = MeasureSpec.getSize(heightMeasureSpec);
   int heightMode = MeasureSpec.getMode(heightMeasureSpec);
   if (widthMode == MeasureSpec.EXACTLY) {
     mWidth = widthSize;
   }

if (heightMode == MeasureSpec.EXACTLY) {
     mHeight = heightSize;
   }
   setMeasuredDimension(mWidth, mHeight);
   mBitmap = Bitmap.createBitmap(300,300, Bitmap.Config.ARGB_8888); //生成一个bitmap
   mCanvas = new Canvas(mBitmap);//讲bitmp放在我们自己的画布上,实际上mCanvas.draw的时候 改变的是这个bitmap对象
 }

然后,我们给他绘制一点东西,用来介绍PorterDuffXfermode


@Override
 protected void onDraw(Canvas canvas) {
   mCanvas.drawCircle(100,100,50,mCirclePaint);

mCanvas.drawRect(100,100,200,200,mWavePaint);
   canvas.drawBitmap(mBitmap,0,0,null);
   super.onDraw(canvas);
 }

嗯,可以看到 是我们现在自己的画布上铺了一个bitmap(这里可以理解canvas为桌子  bitmap为画纸,我们在bimap上画画), 然后在bitmap上画了 一个圆,和一个矩形。最后把我们的mBitmap画到系统的画布上(显示到屏幕上),得到了以下效果。

然后我们用setXfermode()方法给他设置一个mode,这里设置XOR。

Android项目实战手把手教你画圆形水波纹loadingview

可以发现! 相交的地方消失了! 是不是很神奇。
在改一个mode 试试


private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);

Android项目实战手把手教你画圆形水波纹loadingview

可以看到圆形跑到了矩形上面来。然后巨人给我们总结各个模式如了下图,这里给一个说明dst为先画的 src为后画的:.

Android项目实战手把手教你画圆形水波纹loadingview

大家可以根据这个规律试一下。

现在,我们把圆和矩形重叠。模式去掉。


protected void onDraw(Canvas canvas) {

//dst
   mCanvas.drawCircle(150,150,50,mCirclePaint);

/    mWavePaint.setXfermode(mMode);
   //src
   mCanvas.drawRect(100,100,200,200,mWavePaint);
   canvas.drawBitmap(mBitmap,0,0,null);
   super.onDraw(canvas);
 }

我的圆怎么没了。。  其实圆是被覆盖掉了。 然后我们想实现一个效果,就是在圆的范围内,显示矩形的内容,该怎么做呢。自己照着图找找吧哈哈。

我们要实现的是一个圆形的水波纹那种loadingview。。首要就是实现这个水波纹。
这时候贝塞尔曲线就派上用场了。这里采用三阶贝塞尔, 不停地改变X 模拟水波效果。


if (x > 50) {
     isLeft = true;
   } else if (x < 0) {
     isLeft = false;
   }
<span style="white-space:pre">    </span>if (y > -50) { //大于-50是因为辅助点是50 为了让他充满整个屏幕
     y--;
   }    if (isLeft) {
     x = x - 1;
   } else {
     x = x + 1;
   }
   mPath.reset();
   mPath.moveTo(0, y);
   mPath.cubicTo(100 + x*2, 50 + y, 100 + x*2, y-50, mWidth, y);//前两个参数是辅助点
   mPath.lineTo(mWidth, mHeight);//充满整个画布
   mPath.lineTo(0, mHeight);//充满整个画布
   mPath.close();

之后用mCanvas来绘制这个bitmap,要注意的是 绘制之前要清空mBitmap,不然path会重叠


mBitmap.eraseColor(Color.parseColor("#00000000"));

//dst
mCanvas.drawPath(mPath, mPaint);
canvas.drawBitmap(mBitmap, 0, 0, null);

postInvalidateDelayed(10);

 哈,水波效果出来了。接着想办法让他画到一个圆形中。 首先绘制一个圆


mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);

现在让我们回到刚才的问题,如何在dst的范围内绘制src呢。答案是:SRC_IN 你找对了吗?添加模式


//dst
  mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);

mPaint.setXfermode(mMode);
  //src
  mCanvas.drawPath(mPath, mPaint);

canvas.drawBitmap(mBitmap, 0, 0, null);

是不是有点感觉了。如果不这样做 就需要考虑好多问题。动态计算沿着圆弧x,y坐标计算arcTo的范围。

完善一下,添加一个percent来代表进度,让y来根据percent动态改变
y = (int) ((1-mPercent /100f) *mHeight); 

添加setPercent方法


public void setPercent(int percent){
   mPercent = percent;
 }

画上百分比的文字。


String str = mPercent + "%";
   float txtLength = mTextPaint.measureText(str);
   canvas.drawText(mPercent + "%", mWidth / 2-txtLength/2, mHeight / 2, mTextPaint);

然后配合seekBar,最后改改字体大小  画笔透明度。 添加个背景图 就成了效果图上的效果。

是不是很有趣,大家可以动手实现一下!

标签:Android,水波纹
0
投稿

猜你喜欢

  • 改变JAVA窗体属性的操作方法

    2022-02-17 02:10:59
  • Java使用反射调用方法示例

    2022-09-21 16:48:33
  • springsecurity 企业微信登入的实现示例

    2023-06-16 16:39:35
  • C# 使用Log4net添加日志记录的方法

    2021-11-16 01:57:23
  • Android实现图片在屏幕内缩放和移动效果

    2021-10-28 12:24:57
  • Java基于JDK 1.8的LinkedList源码详析

    2021-07-15 03:29:26
  • unity实现翻页效果

    2022-09-01 17:10:15
  • Java 实战项目之CRM客户管理系统的实现流程

    2022-12-01 22:50:54
  • JDK常用命令jps jinfo jstat的具体说明与示例

    2021-08-09 16:03:30
  • 详细解读Android系统中的application标签

    2021-07-10 02:29:46
  • Android仿微信语音聊天功能

    2022-11-24 03:36:12
  • Springboot整合企业微信机器人助手推送消息的实现

    2023-08-18 08:37:37
  • SpringCloud Edgware.SR3版本中Ribbon的timeout设置方法

    2023-03-07 10:45:46
  • Android创建简单发送和接收短信应用

    2022-01-04 18:31:08
  • Java通过jersey实现客户端图片上传示例

    2022-09-17 15:44:24
  • java编译器和JVM的区别

    2023-07-18 20:34:48
  • MyBatis中不建议使用where 1=1原因详解

    2021-08-09 23:25:55
  • Java Redis Redisson配置教程详解

    2022-10-13 06:32:39
  • android实现拍照或从相册选取图片

    2022-08-08 06:55:36
  • android实现点击图片全屏展示效果

    2023-12-06 22:42:25
  • asp之家 软件编程 m.aspxhome.com