进度条是很多软件中必须存在的效果,今天我们就看看直播类app开发实现的进度条效果。

效果&使用

图例分别为:

  • 修改读条起点为y轴正方向
  • 消失性读条
  • 正常读条

使用:

  • 1 在xml中添加控件
<com.lloydfinch.ProgressTrackBarandroid:id="@+id/progress_track_bar"android:layout_width="62dp"android:layout_height="62dp"app:p_second_color="#E91E63"app:p_width="3dp" /><com.lloydfinch.ProgressTrackBarandroid:id="@+id/progress_track_bar2"android:layout_width="62dp"android:layout_height="62dp"app:p_first_color="#18B612"app:p_second_color="#00000000"app:p_width="3dp" /><com.lloydfinch.ProgressTrackBarandroid:id="@+id/progress_track_bar3"android:layout_width="62dp"android:layout_height="62dp"app:p_first_color="#ffd864"app:p_second_color="#1C3F7C"app:p_width="3dp" />
  • 2 在直播类app开发的代码中启动倒计时
val trackBar = findViewById<ProgressTrackBar>(R.id.progress_track_bar)
trackBar.setStartAngle(-90F) // 从-90度开始读条
trackBar.setOnProgressListener { // 进度回调Log.d("ProgressTrackBar", "progress is $it")
}
trackBar.startTask(0) { // 开始计时,传入读条结束的回调Log.d("ProgressTrackBar", "progress run finish")
}// 从0开始计时
findViewById<ProgressTrackBar>(R.id.progress_track_bar2).startTask(0)// 从20开始计时
findViewById<ProgressTrackBar>(R.id.progress_track_bar3).startTask(20)

思路&编码

核心思路就一个: 画原环。我们要画两个圆环,一个下层的完整圆环作为底色,一个上层的圆弧作为进度。重点就是计算圆弧弧度的问题了。

假设当前进度是current,最大进度是max,那么当前圆弧进度就是:(current/max)*360,然后我们直接调用:

// oval: 放置圆弧的矩形
// startAngle: 开始绘制的起点角度,方向是顺时针计算的。0就x正半轴,90就是y轴负半轴
// sweepAngle: 要绘制的圆弧的弧度,就是上述: (current/max)x360
// false: 表示不连接到圆心,表示绘制一个圆弧
canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);

直播类app开发就能绘制出对应的圆弧。

所以,我们这样:

// 绘制下层: 圆形
mPaint.setColor(firstLayerColor);
canvas.drawCircle(x, y, radius, mPaint);// 绘制上层: 圆弧
mPaint.setColor(secondLayerColor);
float sweepAngle = (currentProgress / maxProgress) * 360;
canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);

我们先用下层颜色绘制一个圆形,然后用上层颜色绘制个圆弧,然后不断触发重绘,就能得到想要的效果。

但是,如果我们想要的是: 随着进度变大,圆弧越来越短呢?比如示例图的第二个效果。说白了就是让上层随着时间流逝而变小,直到消失,怎么实现呢?

其实,说白了就是时间越长,弧度越小,直播类app开发做减法即可,我们用(max-current)来作为已读进度,这样随着时间流逝,进度就越来越小。

有人说,这样不对啊,这样(max-current)不就越读越小了吗,这样画出来的弧度就越来越短了,最后完全漏出了底层,给人的感觉是倒着读的。没错,所以,我们只绘制一层,我们用下层颜色来绘制圆弧!这样,随着时间流逝,弧度越来越小,因为圆弧是用下层颜色绘制的,所以视觉上就是: 下层越来越少。给人的感觉就是: 上层越来越大以至于盖住了下层。

逻辑如下:

// 用下层颜色 绘制 剩下的弧度
mPaint.setColor(firstLayerColor);
float leaveAngle = ((maxProgress - currentProgress) / maxProgress) * 360;
canvas.drawArc(oval, startAngle, leaveAngle, false, mPaint);

可以看到,这里直播类app开发只绘制一层,随着时间流逝,圆弧越来越短,给人的感觉就是: 圆弧消失。就达到了示例图中 第二个圆弧的效果。

整体代码如下:

public class ProgressTrackBar extends View {private static final int DEFAULT_FIRST_COLOR = Color.WHITE;private static final int DEFAULT_SECOND_COLOR = Color.parseColor("#FFA12F");private static final int PROGRESS_WIDTH = 6;private static final float MAX_PROGRESS = 360F;private static final int DEFAULT_SPEED = 1;private Paint mPaint;private float startAngle = 0;private int firstLayerColor = DEFAULT_FIRST_COLOR;private int secondLayerColor = DEFAULT_SECOND_COLOR;private final RectF oval = new RectF(); // 圆形轨迹private float maxProgress = MAX_PROGRESS; // 最大进度:msprivate float currentProgress = 0F; // 当前进度:msprivate int speed = DEFAULT_SPEED; // 速度(多长时间更新一次UI):msprivate int progressWidth = PROGRESS_WIDTH; // 进度条宽度private OnProgressFinished onProgressFinished;private Handler taskHandler;private OnProgress runnable; //进度回调// 顶层颜色是否是透明private boolean isSecondColorTransparent = false;public ProgressTrackBar(Context context) {super(context);init();}public ProgressTrackBar(Context context, @Nullable AttributeSet attrs) {super(context, attrs);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressTrackBar);firstLayerColor = typedArray.getColor(R.styleable.ProgressTrackBar_p_first_color, DEFAULT_FIRST_COLOR);secondLayerColor = typedArray.getColor(R.styleable.ProgressTrackBar_p_second_color, DEFAULT_SECOND_COLOR);startAngle = typedArray.getFloat(R.styleable.ProgressTrackBar_p_start, 0F);progressWidth = typedArray.getDimensionPixelSize(R.styleable.ProgressTrackBar_p_width, PROGRESS_WIDTH);maxProgress = typedArray.getDimension(R.styleable.ProgressTrackBar_p_max_progress, MAX_PROGRESS);typedArray.recycle();init();}public ProgressTrackBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {refresh();mPaint = new Paint();mPaint.setStyle(Paint.Style.STROKE);mPaint.setAntiAlias(true);mPaint.setStrokeCap(Paint.Cap.ROUND);mPaint.setStrokeWidth(progressWidth);}public void setFirstLayerColor(int firstLayerColor) {this.firstLayerColor = firstLayerColor;}public void setSecondLayerColor(int secondLayerColor) {this.secondLayerColor = secondLayerColor;refresh();}public void setMaxProgress(float maxProgress) {this.maxProgress = maxProgress;}public void setSpeed(int speed) {this.speed = speed;}public void setStartAngle(float startAngle) {this.startAngle = startAngle;}public void setProgressWidth(int progressWidth) {this.progressWidth = progressWidth;}public void setOnProgressListener(OnProgress runnable) {this.runnable = runnable;}public void setOnProgressFinished(OnProgressFinished onProgressFinished) {this.onProgressFinished = onProgressFinished;}private void initTask() {taskHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {if (currentProgress < maxProgress) {currentProgress += speed;postInvalidate();if (runnable != null) {runnable.onProgress(currentProgress);}taskHandler.sendEmptyMessageDelayed(0, speed);} else {stopTask();}}};}private void refresh() {isSecondColorTransparent = (secondLayerColor == Color.parseColor("#00000000"));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int x = getWidth() >> 1;int y = getHeight() >> 1;int center = Math.min(x, y);int radius = center - progressWidth;int left = x - radius;int top = y - radius;int right = x + radius;int bottom = y + radius;oval.set(left, top, right, bottom);// 这里需要处理一下上层是透明的情况if (isSecondColorTransparent) {// 用下层颜色 绘制 剩下的弧度mPaint.setColor(firstLayerColor);float leaveAngle = ((maxProgress - currentProgress) / maxProgress) * 360;canvas.drawArc(oval, startAngle, leaveAngle, false, mPaint);} else {// 绘制下层mPaint.setColor(firstLayerColor);canvas.drawCircle(x, y, radius, mPaint);// 绘制上层mPaint.setColor(secondLayerColor);float sweepAngle = (currentProgress / maxProgress) * 360;canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);}}public void startTask(int progress) {currentProgress = progress;initTask();taskHandler.sendEmptyMessage(0);}public void startTask(int progress, OnProgressFinished onProgressFinished) {this.onProgressFinished = onProgressFinished;currentProgress = progress;initTask();taskHandler.sendEmptyMessage(0);}public void stopTask() {if (onProgressFinished != null) {onProgressFinished.onFinished();}if (taskHandler != null) {taskHandler.removeCallbacksAndMessages(null);}}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();stopTask();}public interface OnProgressFinished {void onFinished();}public interface OnProgress {void onProgress(float progress);}
}

总结

核心思路就一个: 直播类app开发如果上层要用透明盖住下层,这是不可能的,所以不如用上层的相对值去绘制下层
声明:本文由云豹科技转发自奔波儿灞取经博客,如有侵权请联系作者删除

直播类app开发,实现一个进度条效果相关推荐

  1. 直播类app开发,如何实现直播的相关功能

    上篇文章完成了直播的简单业务,我们可以慢慢完善这个直播类app开发, 例如附近直播,直播礼物,直播回放, 当然直播类app开发的实际业务要比我说的复杂,博主这里提供一个思路 附近直播 现在直播类app ...

  2. iOS 直播类APP开发流程

    (一) iOS 直播类APP开发流程分解: 1 . 音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放显示 1.数据采集: 摄像机及拾音器收集视频及音频数据,此时得 ...

  3. 分析一下,直播类app开发需要哪些技术

    直播技术总结 直播总结 1.概述 关于直播类app开发的技术文章不少,成体系的不多.我们将用这篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播类 ...

  4. (转载)iOS直播类APP开发流程

    转载自博主:iOS_developer_zhong,博客地址: http://blog.csdn.net/zhonggaorong/article/details/51483282 本文为大家分享了i ...

  5. 直播类app开发的开屏广告是怎样实现的

    直播类app开发时,技术人员需要注意一个功能,那就是开屏广告,接下来就分析一下直播类app开发是怎样实现开屏广告的. 一) 开屏广告 效果如下 支持网络资源缓存策略 支持本地和网络6种类型广告 本地i ...

  6. iOS直播类APP开发流程解析

    前言 个人认为要想把直播从零开始做出来,绝对是牛逼中的牛逼,大牛中的大牛,因为直播中运用到的技术难点非常之多,视频/音频处理,图形处理,视频/音频压缩,CDN分发,即时通讯等技术,每一个技术都够学几年 ...

  7. iOS 直播类APP开发流程解析

    1 . 音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放显示 1.数据采集:摄像机及拾音器收集视频及音频数据,此时得到的为原始数据 涉及技术或协议: 摄像机:CC ...

  8. iOS 直播类APP开发流程分解:

    1 . 音视频处理的一般流程: 数据采集→数据编码→数据传输(流媒体服务器) →解码数据→播放显示 1.数据采集:摄像机及拾音器收集视频及音频数据,此时得到的为原始数据 涉及技术或协议: 摄像机:CC ...

  9. 在线视频直播类app软件如何开发?

    最近两年,要说手机APP开发最火的行业非视频直播APP莫属,不少企业通过直播视频手机软件获得了巨大的成功,也就使得后期不少企业进入视频直赔软件开发的行业,可是开发一个直播视频APP并不是那么简单的,虽 ...

最新文章

  1. EVA 4400存储数据恢复报告
  2. python如何移动图片_python之详细图像仿射变换讲解(图像平移、旋转、缩放、翻转),一文就够了,赶紧码住...
  3. 微小宝公众号排行榜_榜单 广东省技工院校微信公众号排行榜(第51期)
  4. [NOI2002]荒岛野人 数论
  5. pearson, kendall 和spearman三种相关分析方法的区别
  6. 新西兰储备银行数据遭泄露
  7. 【免费毕设】PHP论文格式化系统(系统+论文)
  8. AS3 库资源 很多非常有用的类库
  9. 网络安全:9次实验带你学会网安
  10. DPDK示例l3fwd性能测试
  11. 上海旅行日志 2012年7月14日
  12. centos刻录工具_centos u盘引导制作工具
  13. 词根词缀整理2019-3-20
  14. java aspose 导出word_使用Aspose.word导出word报告
  15. Matlab提示Ill-conditioned covariance created at iteration
  16. 计算机图形学(六)-光栅化、采样、走样与反走样、滤波与卷积
  17. 京东商品的历史价格走势
  18. wps参考文献乱码。英文的行间距怎么调?
  19. 请编写一个正方体类,类的私有数据成员是边长,要求用公有成员函数实现以下功能:1. 由键盘分别输入正方体的边长2. 计算并输出正方体的体积
  20. 2021SC@SDUSC(dolphinscheduler- common3)

热门文章

  1. 惊呆了!被公司辞退拿了 22 万补偿金,原东家称每月涨薪 7000,只要退还 22 万...
  2. 【Java】File类简单概述
  3. 在线FLV播放器实现
  4. go.uber.org/zap
  5. unity NavMesh网格寻路
  6. iso快门光圈_相机最重要的设置:快门速度,光圈和ISO解释
  7. Golang URL query contains semicolon 报错解决方案
  8. ansible批量化脚本
  9. OC中常用的数学函数以及浮点处理函数
  10. 20190513——python基础(列表、数据类型:字典、列表和字典的异同)