目录:
1、前言
2、背景
3、组件功能展示
4、Sample解析
5、Library解析
6、作者系列文章合集

前言

基于安卓平台的进度轮组件ProgressWheel(https://github.com/Alford087/ProgressWheel),实现了鸿蒙化迁移和重构,代码已经开源到(https://gitee.com/isrc_ohos/progress-wheel_ohos),欢迎各位下载使用并提出宝贵意见!

背景

进度轮是UI界面中常见的组件,通常用于向用户显示某个耗时操作完成的百分比,例如:加载状态、下载进度、刷新网页等。进度轮可以动态地显示操作进度,避免用户误以为程序失去响应,从而更好地提高用户界面的友好性。

组件功能展示

基于鸿蒙系统,通过自定义控件属性的方式实现了进度轮组件,该组件支持进度轮的旋转、进度增加两种功能。

1、旋转

点击“Start spinning”按钮,此时进度轮会开始旋转,在旋转过程中按钮上的“Start spinning”变成“Stop spinning”,点击“Stop spinning”用户可以随时停止旋转,效果如图1所示。进度轮旋转功能主要用于展示服务器正在加载数据的状态,此时的作用和加载动画库AVLoadingIndicatorView类似。

图1 进度轮旋转

2、进度增加

点击“Increment”按钮,进度轮会定量增加进度,进度值会实时显示在进度轮的中间,效果如图2所示,进度增加功能主要用于展示服务器加载数据的进度。

图2 按钮控制进度增加

Sample解析

在Sample中向用户提供了5个场景,分别是:(1)进度轮旋转、(2)按钮控制进度增加、(3)原生进度条控制进度增加、(4)背景改变、(5)样式改变。其中(1)、(2)两种场景较为简单,均为按钮触发,调用ProgressWheel类的开始旋转、进度增加方法即可,在Library解析部分会详解解释。此处重点介绍(3)、(4)、(5)三种场景。

1、原生进度条控制进度增加

图3 原生进度条控制进度增加

原生进度条是指鸿蒙系统的基本组件slider,它也可以用于显示内容加载或操作处理的进度,此处我们通过拖动原生进度条来改变进度轮的进度值,并将进度值实时显示。效果如图3所示,代码实现如下:

@Override
public void onProgressUpdated(Slider seekBar, int i, boolean b){
//原生进度条和进度轮换算,100代表原生进度条的进度最大值,360代表进度轮的进度最大值
double progress = 360.0 * (seekBar.getProgress() / 100.0);
//进度轮进度设置
wheel.setProgress((int) progress);
}

2、背景改变

图4 进度轮背景改变

使用Random 类产生随机数,特定处理后作为背景像素点。点击“Random bg”按钮,背景像素点显示,进度轮的背景会发生随机变化。效果如图4所示。代码如下:

//背景改变
private static void randomBg(ProgressWheel wheel) {
//随机产生背景元素
Random random = new Random();
int firstColour = random.nextInt();//随机数获取
int secondColour = random.nextInt();
int patternSize = (1 + random.nextInt(3)) * 8;//随机数处理
int patternChange = (1 + random.nextInt(3)) * 8;
int[] pixels = new int[patternSize];
for (int i = 0; i < patternSize; i++) {
pixels[i] = (i > patternChange) ? firstColour : secondColour;//得到像素点
}
PixelMap.InitializationOptions options=new PixelMap.InitializationOptions();
options.size=new Size(1,patternSize);
options.pixelFormat=PixelFormat.ARGB_8888;
//设置背景元素
wheel.setRimShader(new PixelMapShader(
new PixelMapHolder(PixelMap.create(pixels, options)),
Shader.TileMode.REPEAT_TILEMODE,
Shader.TileMode.REPEAT_TILEMODE), Paint.ShaderType.RADIAL_SHADER);
}

3、样式改变

图5 进度轮样式改变

通过自定义进度轮的长度、宽度、背景等来设计不同的样式,点击“A different style”按钮触发样式改变,效果如图5所示,代码如下:

//样式改变
private static void styleRandom(ProgressWheel wheel, Context ctx) {
wheel.setRimShader(null, Paint.ShaderType.RADIAL_SHADER);
wheel.setRimColor(0xFFFFFFFF);
wheel.setCircleColor(0x00000000);//内圆颜色
wheel.setBarColor(0xFF000000);//进度轮体颜色
wheel.setContourColor(0xFFFFFFFF);//外圆颜色
wheel.setBarWidth(pxFromDp(ctx, 8));//宽度
wheel.setBarLength(pxFromDp(ctx, 100));//长度
wheel.setSpinSpeed(2);//旋转速度
wheel.setDelayMillis(3);//间隔时间
}

Library解析

1.功能实现

(1)进度轮绘制。

该功能是通过ProgressWheel类来实现的,在该类中首先声明setupBounds()、setupPaints()方法,后使用canvas绘制进度轮,设定内圆、外圆、条纹等、文字等属性。文字用于显示进度轮的属性值,不局限于显示当前进度。

public ProgressWheel(Context context)  {
super(context);
DrawTask task = (component, canvas) -> {
//初始化元素边界
setupBounds();
//初始化绘制属性
setupPaints();
//绘制内圆
canvas.drawArc(innerCircleBounds, new Arc(360, 360, false), circlePaint);
//绘制外圆
canvas.drawArc(circleBounds, new Arc(360, 360, false), rimPaint);
canvas.drawArc(circleOuterContour, new Arc(360, 360, false), contourPaint);
//绘制条纹
if (isSpinning) {
canvas.drawArc(circleBounds, new Arc(progress - 90, barLength, false), barPaint);
} else {
canvas.drawArc(circleBounds, new Arc(-90, progress, false), barPaint);
}
//设置文字于圆心处显示
float textHeight = textPaint.descent() - textPaint.ascent();
float verticalTextOffset = (textHeight / 2) - textPaint.descent();
for (String line : splitText) {
float horizontalTextOffset = textPaint.measureText(line) / 2;
canvas.drawText(
textPaint,
line,
(float) component.getWidth() / 2 - horizontalTextOffset,
(float) component.getHeight() / 2 + verticalTextOffset);
}
//旋转时在不同的位置画进度条
if (isSpinning) {
scheduleRedraw();
}
};
addDrawTask(task);
}

(2)进度轮旋转

该功能只提供给用户进度轮旋转的展示形式,不提供当前线程的量化进度。

1)开始旋转。进度轮进入旋转模式时,需要开辟新的线程,每隔一定时间重新绘制进度,来达到旋转的效果。

public void startSpinning() {
isSpinning = true;//设置当前为旋转状态
pinHandler.sendEvent(0);//更新进度
}

2)停止旋转。进度轮停止旋转时,进度值被置零。

public void stopSpinning() {
isSpinning = false;//设置当前为停止状态
progress = 0;//进度清零
invalidate();
}

(3)进度增加

该功能需提前设定好增量,每次增加固定的进度,进度的最大值设置为360,当超过最大值时,进度值被置零。该模式在旋转时提供当前的量化进度数据,用户可以清晰地了解当前的线程进度,是一种对用户更友好的交互模式。

public void incrementProgress(int amount) {
isSpinning = false;//增加进度时进度轮不旋转
progress+= amount;//定量增加
if (progress > 360){
progress %= 360;//超过360会自动重置
}
invalidate();
}

2.移植方法

本组件在移植时大部分采用API替换的方法,少数方法需要重写,如处理进度轮旋转的时候重写spinHandler()方法,该方法的功能是:进度轮旋转时在不同的像素位置绘制进度条,移动的位置超过360度则置为0度,重新旋转。代码如下:

//每次绘制要移动的像素数目
private float spinSpeed = 2f;
//绘制过程的时间间隔
private int delayMillis = 100;
private EventHandler spinHandler = new EventHandler(EventRunner.getMainEventRunner())
{
@Override
public void processEvent(InnerEvent msg)
{
invalidate();
if (isSpinning)
{
//更新画进度的位置
progress += spinSpeed;
//要移动的像素数目超过360则重置
if (progress > 360)
{
progress = 0;
}
spinHandler.sendEvent(0, delayMillis);
}
super.processEvent(msg);
}
};

项目贡献人

刘磊 郑森文 朱伟 陈美汝 张馨心

作者:小雪糕123
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

鸿蒙开源第三方组件——进度轮ProgressWheel的更多相关文章

  1. 鸿蒙开源第三方组件——SlidingMenu_ohos侧滑菜单组件

    目录: 1.前言 2.背景 3.效果展示 4.Sample解析 5.Library解析 6.<鸿蒙开源第三方组件>文章合集 前言 基于安卓平台的SlidingMenu侧滑菜单组件(http ...

  2. 鸿蒙开源第三方组件 ——B站开源弹幕库引擎的迁移(上)

    鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录: 一.弹幕库的基础知识 二.弹幕库的使用方法 三.sample解析 四.作者系列文章合集 前言 ...

  3. 鸿蒙开源第三方件组件——轮播组件Banner

    目录: 1.功能展示 2.Sample解析 3.Library解析 4.<鸿蒙开源第三方组件>系列文章合集 前言 基于安卓平台的轮播组件Banner(https://github.com/ ...

  4. 【全网首发】鸿蒙开源三方组件--强大的弹窗库XPopup组件

    目录: 1.介绍 2.效果一览 3.依赖 4.如何使用 5.下载链接 6.<鸿蒙开源三方组件>文章合集 1. 介绍 ​ XPopup是一个弹窗库,可能是Harmony平台最好的弹窗库.它从 ...

  5. 【全网首发】鸿蒙开源三方组件--跨平台自适应布局yoga组件

    目录: 1.介绍 2.如何使用 3.集成方式 4.附录1:FlexBox科普 5.附录2:相关资料 介绍 yoga是facebook打造的一个跨IOS.Android.Window平台在内的布局引擎, ...

  6. react native 第三方组件react-native-swiper 轮播组件

    github地址:https://github.com/leecade/react-native-swiper 使用方法:安装:npm i react-native-swiper –save 查看模块 ...

  7. 鸿蒙第三方组件——SwipeCaptcha滑动拼图验证组件

    目录:1.组件效果展示2.Sample解析3.<鸿蒙第三方组件>系列文章合集 前言 基于安卓平台的滑动拼图验证组件SwipeCaptcha( https://github.com/mcxt ...

  8. iOS 项目中用到的一些开源库和第三方组件

    iOS 项目中用到的一些 iOS 开源库和第三方组件 分享一下我目前所在公司 iOS 项目中用到的一些 iOS 开源库和第三方组件, 感谢开源, 减少了我们的劳动力, 节约了我们大量的时间, 让我们有 ...

  9. 公司用中会用到的iOS开源库和第三方组件(不断更新...)

    分享一些目前我个人接触到的一些第三方组件和开源的库, 感谢开源, 减少了我们的开发成本, 节约了我们大量的时间, 让我们有更多的时间和精力专注做我们自己的产品.总有没有接触过的 , 总有你会用到的 , ...

随机推荐

  1. Java中的transient关键字,使用小结

    transient关键字的介绍: 一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java的这种序列化模式为开发者提供了很多便利,可以不必关系具体序列化的过程,只要这个类实现了S ...

  2. OSPF特殊区域和LSA

    OSPF路由计算优选次序: (1) 直连路由:本路由器发起的LSA 1.2: (2) 区域内路由:O: LSA 1.2: (3) 区域间路由:O IA: LSA 3: (4) 1类外部路由:O E1: ...

  3. 网际互连__OSI七层模型

    概述 OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型 ,是一个逻辑上的定义.一个规范.它把网络从逻辑上分为了7层.每一层都有相关. ...

  4. 人均年薪50万以上,docker到底是什么?为什么这么火?

    为什么要使用Docker? 场景一:公司双十一买了一堆服务器,技术总监让你给它们一个个都配置上JDK.Mysql.Redis等软件环境. 你心里小声嘀咕:"这总监不讲武德!"然后你 ...

  5. SQL中字符串截取函数(SUBSTRING)

    1.left(name,4)截取左边的4个字符 列: SELECT LEFT(201809,4) 年 结果:2018 2.right(name,2)截取右边的2个字符 SELECT RIGHT(201 ...

  6. Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords(贪心/数学)

    题目链接:https://codeforces.com/contest/1366/problem/A 题意 有两个数 $a$ 和 $b$,每次可以选择从一个数中取 $2$,另一个数中取 $1$,问最多 ...

  7. JavaScript——匿名函数和闭包

    匿名函数就是没有名字的函数 闭包就是一个函数中的另一个函数 函数可以不加分号,但是语句要加!! 可以把匿名函数的返回值赋值给变量!! box()时返回里面的函数,再加一个()就会返回里面那函数的值(浅 ...

  8. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  9. 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现

    上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...

  10. 自己动手实现springboot运行时执行java源码(运行时编译、加载、注册bean、调用)

    看来断点.单步调试还不够硬核,根本没多少人看,这次再来个硬核的.依然是由于apaas平台越来越流行了,如果apaas平台选择了java语言作为平台内的业务代码,那么不仅仅面临着IDE外的断点.单步调试 ...