技术:Android+java

概述

看见猎豹清理大师的内存开口圆环比例进度 挺有意思的,于是就是想自己实现下这样的效果,于是反编译了猎豹清理 大师的app看了下,原来是有两张图,于是脑子里就过了下思路,利用上下两张图,旋转上面张图以及使用 PorterDuffXfermode 来设置合适的渲染模式,就可以达到效果

详细

代码下载:http://www.demodashi.com/demo/14680.html

一、概述

看见猎豹清理大师的内存开口圆环比例进度 挺有意思的,于是就是想自己实现下这样的效果,于是反编译了猎豹清理

大师的app看了下,原来是有两张图,于是脑子里就过了下思路,利用上下两张图,旋转上面张图以及使用

PorterDuffXfermode 来设置合适的渲染模式,就可以达到效果。下面看看咱们的效果吧

二、演示效果图

三、Xfermode渲染模式简介:

xfermode影响在Canvas已经有的图像上绘制新的颜色的方式 
* 正常的情况下,在图像上绘制新的形状,如果新的Paint不是透明的,那么会遮挡下面的颜色. 
* 如果新的Paint是透明的,那么会被染成下面的颜色

下面的Xfermode子类可以改变这种行为:

AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素XOR操作。

PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

这里不得不提到那个经典的图:

上面的16种模式的说明如下:

从上面我们可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:

1.PorterDuff.Mode.CLEAR

所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC

显示上层绘制图片
3.PorterDuff.Mode.DST

显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER

正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER

上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN

取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN

取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT

取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT

取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP

取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP

取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR

异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN

取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN

取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY

取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN

取两图层全部区域,交集部分变为透明色

四、自定义开口圆环View的实现

1、初始化绘制所需的画笔,字体颜色、大小等变量

public XCArcProgressBar(Context context, AttributeSet attrs,int defStyleAttr) {super(context, attrs, defStyleAttr);// TODO Auto-generated constructor stubdegrees =  0;paint  =  new Paint();//从attrs.xml中获取自定义属性和默认值TypedArray typedArray  = context.obtainStyledAttributes(attrs, R.styleable.XCRoundProgressBar);textColor  =typedArray.getColor(R.styleable.XCRoundProgressBar_textColor, Color.RED);textSize = typedArray.getDimension(R.styleable.XCRoundProgressBar_textSize, 15);max = typedArray.getInteger(R.styleable.XCRoundProgressBar_max, 100);isDisplayText  =typedArray.getBoolean(R.styleable.XCRoundProgressBar_textIsDisplayable, true);typedArray.recycle();}

2、在onDraw()中绘制出来

在onDraw()方法中利用PorterDuffXfermode渲染模式绘制两张开口圆环Bitmap,并计算前景图的旋转角度,从而达到效果图效果。

首先先绘制底部背景图,然后绘制进度前景图,最后利用PorterDuffXfermode的渲染模式和旋转角度比例来进行前景图和背景图的遮罩处理。

@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);int width = getWidth();int height = getHeight();int centerX = getWidth() / 2;// 获取中心点X坐标int centerY = getHeight() / 2;// 获取中心点Y坐标Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);Canvas can = new Canvas(bitmap);// 绘制底部背景图bmpTemp = Utils.decodeCustomRes(getContext(), R.drawable.arc_bg);float dstWidth = (float) width;float dstHeight = (float) height;int srcWidth = bmpTemp.getWidth();int srcHeight = bmpTemp.getHeight();can.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG));// 抗锯齿Bitmap bmpBg = Bitmap.createScaledBitmap(bmpTemp, width, height, true);can.drawBitmap(bmpBg, 0, 0, null);// 绘制进度前景图Matrix matrixProgress = new Matrix();matrixProgress.postScale(dstWidth / srcWidth, dstHeight / srcWidth);bmpTemp = Utils.decodeCustomRes(getContext(), R.drawable.arc_progress);Bitmap bmpProgress = Bitmap.createBitmap(bmpTemp, 0, 0, srcWidth,srcHeight, matrixProgress, true);degrees = progress * 270 / max - 270;//遮罩处理前景图和背景图can.save();can.rotate(degrees, centerX, centerY);paint.setAntiAlias(true);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));can.drawBitmap(bmpProgress, 0, 0, paint);can.restore();if ((-degrees) >= 85) {int posX = 0;int posY = 0;if ((-degrees) >= 270) {posX = 0;posY = 0;} else if ((-degrees) >= 225) {posX = centerX / 2;posY = 0;} else if ((-degrees) >= 180) {posX = centerX;posY = 0;} else if ((-degrees) >= 135) {posX = centerX;posY = 0;} else if ((-degrees) >= 85) {posX = centerX;posY = centerY;}if ((-degrees) >= 225) {can.save();Bitmap dst = bitmap.createBitmap(bitmap, 0, 0, centerX, centerX);paint.setAntiAlias(true);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));Bitmap src = bmpBg.createBitmap(bmpBg, 0, 0, centerX, centerX);can.drawBitmap(src, 0, 0, paint);can.restore();can.save();dst = bitmap.createBitmap(bitmap, centerX, 0, centerX, height);paint.setAntiAlias(true);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));src = bmpBg.createBitmap(bmpBg, centerX, 0, centerX, height);can.drawBitmap(src, centerX, 0, paint);can.restore();} else {can.save();Bitmap dst = bitmap.createBitmap(bitmap, posX, posY, width- posX, height - posY);paint.setAntiAlias(true);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));Bitmap src = bmpBg.createBitmap(bmpBg, posX, posY,width - posX, height - posY);can.drawBitmap(src, posX, posY, paint);can.restore();}}//绘制遮罩层位图canvas.drawBitmap(bitmap, 0, 0, null);// 画中间进度百分比字符串paint.reset();paint.setStrokeWidth(0);paint.setColor(textColor);paint.setTextSize(textSize);paint.setTypeface(Typeface.DEFAULT_BOLD);int percent = (int) (((float) progress / (float) max) * 100);// 计算百分比float textWidth = paint.measureText(percent + "%");// 测量字体宽度,需要居中显示if (isDisplayText && percent != 0) {canvas.drawText(percent + "%", centerX - textWidth / 2, centerX+ textSize / 2 - 25, paint);}//画底部开口处标题文字paint.setTextSize(textSize/2);textWidth = paint.measureText(title);canvas.drawText(title, centerX-textWidth/2, height-textSize/2, paint);}

3、设置比例进度的同步接口方法,主要供刷新进度比例用。

/*** 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步* 刷新界面调用postInvalidate()能在非UI线程刷新* @author caizhiming*/ public synchronized void setProgress(int progress) {if(progress < 0){throw new IllegalArgumentException("progress must more than 0");}if(progress > max){this.progress = progress;}if(progress <= max){this.progress = progress;postInvalidate();}}

四、项目代码目录结构图

代码下载:http://www.demodashi.com/demo/14680.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

转载于:https://www.cnblogs.com/demodashi/p/10503286.html

Android 自定义控件-高仿猎豹清理大师自定义内存开口圆环控件相关推荐

  1. Android 自定义View修炼-高仿猎豹清理大师自定义内存开口圆环比例进度View

    一.概述 看见猎豹清理大师的内存开口圆环比例进度 挺有意思的,于是就是想自己实现下这样的效果,于是反编译了猎豹清理 大师的app看了下,原来是有两张图,于是脑子里就过了下思路,利用上下两张图,旋转上面 ...

  2. 【安卓笔记】仿猎豹清理大师波浪效果

    先来看效果: 实现方式----->自定义控件 核心代码: [java] view plain copy package com.example.wavedemo1; import android ...

  3. 仿猎豹清理大师波浪效果

    转载自:http://blog.csdn.net/chdjj/article/details/38142953 先来看效果: 实现方式----->自定义控件 核心代码: package com. ...

  4. Android自定义控件----高仿Android酷狗播放条(YluoSeekBar)

    发一个高仿Android版本的酷狗进度条. 是继承SeekBar实现的,代码比较简单就不详细说.用法和原生的SeekBar一样.项目放在我的github上.github地址 效果如下图所示:

  5. 高仿摩拜解锁单车的加载控件

    一.写在前面 最近在下班骑车回家的过程中,发现摩拜单车的解锁进度条还是挺有意思的,它是一直转,根据进度增大圆弧角度,最后有一个打钩的动画,好了,话不多说,马上就来实现一下.上面图的效果不是很好,真实效 ...

  6. Android动画定时lnvaliate,猎豹清理大师波浪动画实现

    感谢段大师的指导! 波浪效果源码: 自定义控件:实现 package com.apidemos2.animation.bezierview; import android.content.Contex ...

  7. 【安卓注意事项】模仿猎豹清理大师波效应

    先来看效果: 实现方式----->自己定义控件 核心代码: package com.example.wavedemo1; import android.content.Context; impo ...

  8. Android 高仿猎豹cm桌面,所有应用,快捷字母栏

    Android 高仿猎豹cm桌面,所有应用,快捷字母栏 直接贴代码了 利用Path,贝塞尔曲线,计算路径,结合插值动画. https://github.com/xufeifandj/SiderLine ...

  9. android汽车之家顶部滑动菜单,Android自定义控件之仿汽车之家下拉刷新

    关于下拉刷新的实现原理我在上篇文章Android自定义控件之仿美团下拉刷新中已经详细介绍过了,这篇文章主要介绍表盘的动画实现原理 汽车之家的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull ...

最新文章

  1. php自动装载编程,php 类自动载入的方法
  2. Windows 10截屏动画失效怎么恢复?
  3. HttpClient在.NET Core中的正确打开方式
  4. 计算机考研各科目分数,考研各科目及分数
  5. vivo S10系列正式发布 引领“自然美”自拍潮流
  6. 之前跳槽面试时整理的一些知识点
  7. NumPy用户指南(2)——安装NumPy
  8. java调用nlpir_ZH奶酪:Java调用NLPIR汉语分词系统
  9. iOS企业ipa(299)证书制作、打包发布全流程
  10. dxp全称_ad对应的器件名称
  11. 如何解决WIN10电脑搜索文件慢的问题办法
  12. 5G推动下,XR的需求“爆发”会来自B端还是C端?
  13. vue知识(四)生命周期、钩子函数、路由
  14. hitTest:(CGPoint)point withEvent:(UIEvent *)event
  15. win7 桌面图标显示不正常
  16. 指针变量访问指向变量
  17. 非常实用,Android引用ttf图标字体库
  18. 迟暮秋水烟低画,谁将婀娜舞霓裳
  19. 刘谦魔术的一个秘密 硬币穿越玻璃的那个。
  20. PXI平台与工业计算机的区别

热门文章

  1. 有哪些入门级蓝牙耳机推荐?盘点2022高性价比蓝牙耳机
  2. 图像分类 - scene classification 研究
  3. pandas中shift(1)是什么用法?
  4. 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
  5. udl文件的制作——用于ADO数据库连接(Oracle举例)
  6. Java网络爬虫入门:第01课:网络爬虫原理
  7. 全地形比赛小车制作分享
  8. 网站服务器数据能不能互通,原神服务器数据是否互通
  9. Maya导入fbx没反应
  10. 【UV打印机】波形开发-开发流程(四)