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

Android 自定义view和属性动画实现充电进度条效果

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

北京

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

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

看不清楚,换张图片

免费获取短信验证码

Android 自定义view和属性动画实现充电进度条效果

近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它开源出来,供有需要的人了解一下相关的内容。

本次实现的功能类似下面的效果:

充电效果

接下来便详细解析一下如何完成这个功能,了解其中的原理,这样就能举一反三,实现其他类似的动画效果了。

详细代码请看大屏幕

https://github.com/crazyandcoder/ChargeProgress

图形解析

一般,我们自定义view时,是将该view进行化解,分成一个一个小部分,然后在重叠起来进行绘制,对于这个项目,也是按照相同的步骤进行。我们用Word来简单解析一下该动画所包含的基本结构。

对于这个充电进度view,我将它分成了ABCD四个部分,下面来详细说明各个部分的组成。

A部分

对于A而言,它是位于整个view的顶部,居中显示,是一个圆角矩形。

B部分

对于B而言,它是整个view的重要组成部分,包含C和D两部分,其中B主要属性就是背景色的设置。

C部分

对于C而言,C就是每一个进度的样式,显示的是未完成的进度条样式。

D部分

对于D而言,它跟C是一样的,只不过是已经完成的进度样式,区别在于颜色的不一样。

其实,这个进度view图形结构还是比较简单的,只是一些简单的矩形,组合而成,因此对于以上的分析,我们轻易的得出一些重要的属性。


<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="charging_progress">
<!--item个数-->
<attr name="cgv_item_count" format="integer" />
<!--边界宽度-->
<attr name="cgv_border_width" format="dimension" />
<!--边界颜色-->
<attr name="cgv_border_color" format="color" />
<!--圆角半径-->
<attr name="cgv_border_cornor_radius" format="dimension" />
<!--充电内每个进度item模块的宽度-->
<attr name="cgv_item_width" format="dimension" />
<!--充电内每个进度item模块的高度-->
<attr name="cgv_item_height" format="dimension" />
<!--充电内每个进度item模块的前景色,充电中的颜色-->
<attr name="cgv_item_charging_class="lazy" data-src" format="color" />
<!--充电内每个进度item模块的背景色,未充电的颜色-->
<attr name="cgv_item_charging_background" format="color" />
<!--view 的背景-->
<attr name="cgv_background" format="color" />
</declare-styleable>
</resources>

对于以上属性,我们在自定义view的时候需要在xml文件中进行设置,如果没有设置的话,我们给出一个默认。然后我们在代码中进行获取这些属性值。


//边界宽度
private float border_width;
//item个数
private int item_count;
//边界宽度
private float item_width;
//边界高度
private float item_height;
//view内部的进度前景色
private int item_charging_class="lazy" data-src;
//view内部的进度背景色
private int item_charging_background;
//view背景色
private int background;
//<!--边界颜色-->
private int border_color;
//圆角半径
private float border_cornor_radius;
//获取xml中设定的属性值
TypedArray array = mContext.obtainStyledAttributes(attrs, R.styleable.charging_progress);
border_width = array.getDimension(R.styleable.charging_progress_cgv_border_width, dp2px(2));
item_height = array.getDimension(R.styleable.charging_progress_cgv_item_height, dp2px(10));
item_width = array.getDimension(R.styleable.charging_progress_cgv_item_width, dp2px(20));
item_charging_class="lazy" data-src = array.getColor(R.styleable.charging_progress_cgv_item_charging_class="lazy" data-src, 0xffffea00);
item_charging_background = array.getColor(R.styleable.charging_progress_cgv_item_charging_background, 0xff544645);
background = array.getColor(R.styleable.charging_progress_cgv_background, 0xff463938);
border_color = array.getColor(R.styleable.charging_progress_cgv_border_color, 0xffb49d7c);
border_cornor_radius = array.getDimension(R.styleable.charging_progress_cgv_border_cornor_radius, dp2px(2));
item_count = array.getInt(R.styleable.charging_progress_cgv_item_count, 10);
array.recycle();

已经获取了自定义属性的值,那么接下来,我们就来具体绘制这些组合图形。

对于一个自定义view,首先要做的就是测量view的大小,而本项目中view的宽度和高度,宽度是好计算的,我们设置view的宽度等于item_widht 乘以2 。但是对于高度的话,因为我们设置了progress的级数,也就是item_count,也设置了item的高度和宽度,所以对于高度,我们可以通过计算item_count 乘以 item_height,再加上间隔数和顶部矩形的就是整个view的高度。同时,我们设定,顶部矩形的高度等于item_height,宽度等于item_widht的一半,中间间隔等于item_height 除以2



@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//总间隔数=(item_count+1) 乘以间隔高度(间隔高度等于item_height的一半)
//总数=item_count 乘以 item_height + 总间隔数 + 顶部一个矩形(高度等于item的高度,宽度等于item的宽度的一半)
mHeight = (int) (item_count * item_height + (item_count + 1) * item_height / 2 + item_height);
mWidth = (int) (2 * item_width);
setMeasuredDimension(mWidth, mHeight);
}

有了上面的设置,接下来我们就可以按部就班的画图了。

对于坐标中心点是设定在左上角,也就是(0,0)处。

画顶部矩形

知道了坐标系的原点,那么顶部矩形的坐标就可以计算了。

首先设置画笔。


mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(border_width);
mPaint.setColor((border_color));

由于顶部矩形的width等于item_widht的一半,所以它的width等于整个view的width的1/6,


int left = mWidth * 3 / 8;
int top = 0;
int right = 5 * mWidth / 8;
int bottom = (int) item_height / 2;
//顶部的矩形
RectF topRect = new RectF(left, top, right, bottom);
canvas.drawRoundRect(topRect, border_cornor_radius, border_cornor_radius, mPaint);

接下来绘制底部的矩形,也就是包含进度item的矩形


//总的进度背景
RectF border = new RectF(0, bottom, mWidth, mHeight);
canvas.drawRoundRect(border, border_cornor_radius, border_cornor_radius, mPaint);

接下来绘制每个item的矩形,对于每个item的坐标,实际上是有规律可循的。


//绘制所有的进度
for (int i = 1; i <= item_count; i++) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor((item_charging_background));
RectF backRect = new RectF(mWidth / 4,
(i + 1) * item_height / 2 + (i - 1) * item_height,
3 * mWidth / 4,
item_height / 2 + i * (3 * item_height / 2));
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
}

绘制动画

对于交流动画,就是从进度0到100的动画显示,依次显示。其实也是对于坐标的计算而已。接下来最终要的功能就是动画的使用了,我们使用的是属性动画呢?因为,常规的动画它不支持啊,很简单。

对于Android属性动画的学习,可以查看这篇文章,稍微了解一下。《Android动画了解》

1、交流动画



private void drawACAnimaiton(Canvas canvas) {
int j = getProgress() / item_count;
//已经充好的进度
for (int i = item_count; i >= (item_count - j); i--) {
RectF backRect = new RectF(mWidth / 4,
(i + 1) * item_height / 2 + (i - 1) * item_height,
3 * mWidth / 4,
item_height / 2 + i * (3 * item_height / 2));
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(item_charging_class="lazy" data-src);
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
}
}

我们首先获取当前的进度,然后依次给它填充背景,这就是已完成的进度表示。

然后使用动画即可,我们设置进度为100,也就是充满,然后设置动画时间是10秒钟,对于下面的动画执行原理是什么呢?其实很简单,获取当前的进度,然后从0开始,依次绘制进度,知道绘制的进度为100就是总的进度,最后再循环执行动画即可。



public void setACAnimation() {
chargeType = AC;
animAC = ObjectAnimator.ofInt(this, "progress", 100);
animAC.setDuration(10 * 1000);
animAC.setInterpolator(new LinearInterpolator());
animAC.setRepeatCount(ValueAnimator.INFINITE);
animAC.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
});
animAC.start();
}

2、直流动画

对于直流动画就稍微比较复杂了。当我们设置了进度后,需要我们预先绘制已完成的进度,然后在下一个进度进行闪烁表示动画,那么该如何完成呢?

首先看绘制代码:



private void drawDCAniamtion(Canvas canvas) {
int j = getProgress() / item_count;
//已经充好的进度
for (int i = item_count; i > (item_count - j); i--) {
RectF backRect = new RectF(mWidth / 4,
(i + 1) * item_height / 2 + (i - 1) * item_height,
3 * mWidth / 4,
item_height / 2 + i * (3 * item_height / 2));
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(item_charging_class="lazy" data-src);
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
}
//下一个进度,隐藏和显示交替执行动画
int i = item_count - j;
if (i > 0) {
RectF backRect = new RectF(mWidth / 4,
(i + 1) * item_height / 2 + (i - 1) * item_height,
3 * mWidth / 4,
item_height / 2 + i * (3 * item_height / 2));
mPaint.setStyle(Paint.Style.FILL);
if (show) {
mPaint.setColor((item_charging_class="lazy" data-src));
} else {
mPaint.setColor((item_charging_background));
}
canvas.drawRoundRect(backRect, border_cornor_radius, border_cornor_radius, mPaint);
}
}

首先绘制已完成的进度,然后在绘制闪烁的部分。



public void setDCAnimation(final int progress) {
chargeType = DC;
animatorDC = ValueAnimator.ofFloat(0, 1);
animatorDC.setInterpolator(new LinearInterpolator());
animatorDC.setDuration(1000);
animatorDC.setRepeatCount(-1);
animatorDC.setRepeatMode(ValueAnimator.RESTART);
animatorDC.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
if (value > 0.5) {
show = true;
} else {
show = false;
}
setProgress(progress);
}
});
animatorDC.start();
}

到这里,就很明了了。对于直流动画,我们使用属性动画中这个ValueAnimator类,它的意思就是从0到1平滑的过渡,在设定的时间内。我们的原理是当达到0.5以上后就设定灰色进度,当小于0.5的话就设置亮色进度,然后在刷新一下view即可。

以上所述是小编给大家介绍的Android 自定义view和属性动画实现充电进度条效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程网网站的支持!

您可能感兴趣的文章:Android属性动画实现炫酷的登录界面Android属性动画实现布局的下拉展开效果Android动画 实现开关按钮动画(属性动画之平移动画)实例代码图文详解Android属性动画Android 动画(View动画,帧动画,属性动画)详细介绍Android 属性动画ValueAnimator与插值器详解Android模拟开关按钮点击打开动画(属性动画之平移动画)Android中编写属性动画PropertyAnimation的进阶实例Android帧动画、补间动画、属性动画用法详解Android动画教程之属性动画详解


免责声明:

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

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

Android 自定义view和属性动画实现充电进度条效果

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

下载Word文档

猜你喜欢

Android 自定义view和属性动画实现充电进度条效果

近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它
2022-06-06

Android自定义view实现进度条指示效果

先看看效果图:首先是布局文件
2022-06-06

Android自定义View实现钟摆效果进度条PendulumView

在网上看到了一个IOS组件PendulumView,实现了钟摆的动画效果。由于原生的进度条确实是不好看,所以想可以自定义View实现这样的效果,以后也可以用于加载页面的进度条。 废话不多说,先上效果图 底部黑边是录制时不小心录上的,可以忽
2022-06-06

Android view自定义实现动态进度条

Android 自定义view实现动态进度条 效果图:这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,从上面的图就可以看出来,左侧、顶部、右侧的线会有被截掉的部分,有懂得希望能给说一下,改进一下,这
2022-06-06

Android自定义View实现动画效果详解

这篇文章主要为大家详细介绍了Android如何通过自定义View实现动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2023-02-02

Android中怎么自定义view实现圆环进度条效果

这篇文章主要讲解了“Android中怎么自定义view实现圆环进度条效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android中怎么自定义view实现圆环进度条效果”吧!核心代码自定义
2023-06-29

Android自定义View实现loading动画加载效果

项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了。 先自定义一个View,继承自Linea
2022-06-06

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

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

Android中怎么通过自定义view实现进度条加载效果

Android中怎么通过自定义view实现进度条加载效果,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。分析图:代码如下:package com.example.dotloa
2023-05-30

Android自定义View实现圆形加载进度条效果的方法

这篇文章将为大家详细讲解有关Android自定义View实现圆形加载进度条效果的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。View仿华为圆形加载进度条效果图实现思路可以看出该View可分为三个部分
2023-05-30

Android怎么自定义View实现圆弧进度效果

这篇文章主要介绍“Android怎么自定义View实现圆弧进度效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么自定义View实现圆弧进度效果”文章能帮助大家解决问题。技术实现1.
2023-07-06

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

Android自定义view实现阻尼效果的加载动画

效果:需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动、衰减振动。[1] 不论是弹簧振
2022-06-06

怎么在Android中通过自定义View实现一个环形进度条效果

这篇文章给大家介绍怎么在Android中通过自定义View实现一个环形进度条效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。功能分析虽然功能比较简单,但是仍然需要仔细分析 1.图标外还有一圈圆圈,可以设置宽度
2023-05-31

Android编程使用自定义View实现水波进度效果示例

本文实例讲述了Android编程使用自定义View实现水波进度效果。分享给大家供大家参考,具体如下:首先上效果图:简介:1.自动适应屏幕大小;2.水波自动横向滚动;3.各种绘制参数可通过修改常量进行控制。代码不多,注释也比较详细,全部贴上:
2023-05-31

Android自定义View实现圆弧进度效果逐步完成过程

在Android开发中,通过自定义View实现自己想要的效果是作为android开发程序员的一项必备技能,自定义View对于android开发来说也是比较难的一项技术
2023-05-16

Android如何实现自定义View圆形和拖动圆、跟随手指拖动效果

小编给大家分享一下Android如何实现自定义View圆形和拖动圆、跟随手指拖动效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!单纯的自定义一个圆非常简单 只需要几步就完成 拖动圆添加实现触摸事件即可我在第一次自定义Vi
2023-05-30

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录