每周自定义View(1) -动态ProgressView
这次就从一个常见的ProgressBark开始吧, 最近的项目中使用了一个Progress显示文件下载进度的功能, 设计给的是一个静态的图片, 也没有说需要具体实现的情况, 后面优化的时候刚好有了性质, 就有了下面的这个AnimatorProgressBar.
支持功能
- 基本的的进度设置(当前默认为0-100)
- 颜色定义, 使用的颜色都是可以设置的, 满足各样的ui需求
- 元素定义, 作为展示的Progress中的线条可以设置宽度和间距
- 动画控制, 动画效果可以设置展示速度, 总有一个组合适合你
设计过程
将相关的view分为了四层, 从下至上分别为
- 背景图层 用于显示整个view的背景
- 进度图层 相当于进度条的背景颜色
- 线段动画图层 在这里绘制出现的线段, 并控制器动画的效果
- 遮罩展示图层 这里使用了遮罩展示的方法, 控制遮罩图层的进度和样式来表现实际的展示效果
实现过程
首先是背景如果绘制的, 简单来说就是两个圆形和一个矩形, 具体的动画效果可以参考下面,
其它的图层基本上也都是比较类似的情况, 除此之外就是线条的实现
其中中心黑色的为展示的区域, 白色的是绘制的区域
代码实现
可编辑参数
-
//下面为可自定义编辑的参数
-
//背景颜色
-
private int viewBackGroundColor;
-
//线条颜色
-
private int viewLineColor;
-
//进度条颜色
-
private int viewProgressColor;
-
//线条见间隔
-
private int offsetLine;
-
//执行动画需要的时间
-
private int animatorTime;
-
//进度变化动画需要的时间
-
private int animatorProgressTime;
-
//画笔/线条的宽度
-
private int paintWidth;
-
背景图层&绘制图层背景
这两个图形的实现比较类似
-
/**
-
* @description 绘制图层背景
-
*/
-
private void getProgressBackground(Canvas canvas){
-
//设置画笔
-
Paint paint = new Paint();
-
paint.setColor(viewProgressColor);
-
-
//确定两个圆形的中心位置及半径
-
int leftCirclePoint = height / 2;
-
int rightCirclePoint = width - leftCirclePoint;
-
int radius = height / 2;
-
-
//绘制左侧和右侧的圆形填充
-
canvas.drawCircle(leftCirclePoint, height >> 1, radius, paint);
-
canvas.drawCircle(rightCirclePoint, height >> 1, radius, paint);
-
-
//绘制中心的矩形填充
-
Rect rect = new Rect(leftCirclePoint, 0, rightCirclePoint, height);
-
canvas.drawRect(rect, paint);
-
}
-
-
/**
-
* @description 绘制背景图层
-
*/
-
private void drawViewBackground(Canvas canvas) {
-
canvas.save();
-
-
Paint paint = new Paint();
-
paint.setColor(viewBackGroundColor);
-
-
int leftCirclePoint = height / 2;
-
int rightCirclePoint = width - leftCirclePoint;
-
int radius = height / 2;
-
-
canvas.drawCircle(leftCirclePoint, height >> 1, radius, paint);
-
canvas.drawCircle(rightCirclePoint, height >> 1, radius, paint);
-
-
Rect rect = new Rect(leftCirclePoint, 0, rightCirclePoint, height);
-
canvas.drawRect(rect, paint);
-
}
绘制遮罩图层
-
/**
-
* @description 绘制遮罩图层
-
*/
-
private Bitmap progressBitmapDst(){
-
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
-
//如果当前进度为0, 则不展示任何内容
-
if (progress == 0){
-
return bitmap;
-
}
-
Canvas canvas = new Canvas(bitmap);
-
-
Paint paint = new Paint();
-
paint.setColor(Color.WHITE);
-
-
-
//遮罩图层宽度与当前progress进度有关
-
int leftCirclePoint = height / 2;
-
int rightCirclePoint = leftCirclePoint (int) ((width - height) / 1f * progress / 100f);
-
-
int radius = height / 2;
-
-
canvas.drawCircle(leftCirclePoint, height >> 1, radius, paint);
-
canvas.drawCircle(rightCirclePoint, height >> 1, radius, paint);
-
-
Rect rect = new Rect(leftCirclePoint, 0, rightCirclePoint, height);
-
canvas.drawRect(rect, paint);
-
-
-
return bitmap;
-
}
绘制线条动画
-
/**
-
* @description 绘制线条动画
-
*/
-
private void getProgressLines(Canvas canvas){
-
Paint paint = new Paint();
-
paint.setColor(viewLineColor);
-
-
//设置画笔宽度
-
paint.setStrokeWidth(paintWidth);
-
-
//设置画笔圆形边界
-
paint.setStrokeCap(Paint.Cap.ROUND);
-
//todo 动画效果展示优化
-
canvas.translate(-offsetLine * 2, 0);
-
//offsetAnimator 为动画展示时使用, 每次移动一定的长度,
-
//通过连续的移动来实现视觉上的动画效果
-
canvas.translate(offsetAnimator, 0);
-
canvas.save();
-
-
int indexOffset = 0;
-
-
//依次绘制线条
-
do {
-
//绘制右上到左下的线条
-
canvas.drawLine(20, -20, -offsetLine - 20, height 20, paint);
-
indexOffset = offsetLine;
-
//偏移位置
-
canvas.translate(offsetLine, 0);
-
}while (indexOffset < width offsetLine * 4);
-
-
canvas.restore();
-
}
动画效果
-
/**
-
* @description 进度变化动画
-
* @param startProgress
-
* @param endProgress
-
*/
-
public void startProgressAnimator(int startProgress, int endProgress){
-
//动画差值范围
-
ValueAnimator va = ValueAnimator.ofFloat(startProgress, endProgress);
-
va.setDuration(animatorProgressTime);
-
//线性取值
-
va.setInterpolator(new LinearInterpolator());
-
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-
-
public void onAnimationUpdate(ValueAnimator valueAnimator) {
-
progress = (float) valueAnimator.getAnimatedValue();
-
invalidate();
-
}
-
-
});
-
-
-
va.start();
-
}
-
-
-
/**
-
* @description 开始动画
-
*/
-
public void startAnimator(){
-
//动画差值范围
-
ValueAnimator va = ValueAnimator.ofFloat(0f, offsetLine);
-
//循环播放
-
va.setRepeatCount(ValueAnimator.INFINITE);
-
va.setDuration(animatorTime);
-
//线性取值
-
va.setInterpolator(new LinearInterpolator());
-
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-
-
public void onAnimationUpdate(ValueAnimator valueAnimator) {
-
offsetAnimator = (float) valueAnimator.getAnimatedValue();
-
invalidate();
-
}
-
});
-
-
va.start();
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcabge
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01