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

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第1张

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://HarmonyOS.51cto.com

前言

基于安卓平台的进度轮组件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类似。

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第2张

图1 进度轮旋转

2、进度增加

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

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第3张

图2 按钮控制进度增加

Sample解析

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

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

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第4张

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

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

  1. @Override
  2. publicvoidonProgressUpdated(SliderseekBar,inti,booleanb){
  3. //原生进度条和进度轮换算,100代表原生进度条的进度最大值,360代表进度轮的进度最大值
  4. doubleprogress=360.0*(seekBar.getProgress()/100.0);
  5. //进度轮进度设置
  6. wheel.setProgress((int)progress);
  7. }

2、背景改变

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第5张

图4 进度轮背景改变

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

  1. //背景改变
  2. privatestaticvoidrandomBg(ProgressWheelwheel){
  3. //随机产生背景元素
  4. Randomrandom=newRandom();
  5. intfirstColour=random.nextInt();//随机数获取
  6. intsecondColour=random.nextInt();
  7. intpatternSize=(1+random.nextInt(3))*8;//随机数处理
  8. intpatternChange=(1+random.nextInt(3))*8;
  9. int[]pixels=newint[patternSize];
  10. for(inti=0;i<patternSize;i++){
  11. pixels[i]=(i>patternChange)?firstColour:secondColour;//得到像素点
  12. }
  13. PixelMap.InitializationOptionsoptions=newPixelMap.InitializationOptions();
  14. options.size=newSize(1,patternSize);
  15. options.pixelFormat=PixelFormat.ARGB_8888;
  16. //设置背景元素
  17. wheel.setRimShader(newPixelMapShader(
  18. newPixelMapHolder(PixelMap.create(pixels,options)),
  19. Shader.TileMode.REPEAT_TILEMODE,
  20. Shader.TileMode.REPEAT_TILEMODE),Paint.ShaderType.RADIAL_SHADER);
  21. }

3、样式改变

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第6张

图5 进度轮样式改变

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

  1. //样式改变
  2. privatestaticvoidstyleRandom(ProgressWheelwheel,Contextctx){
  3. wheel.setRimShader(null,Paint.ShaderType.RADIAL_SHADER);
  4. wheel.setRimColor(0xFFFFFFFF);
  5. wheel.setCircleColor(0x00000000);//内圆颜色
  6. wheel.setBarColor(0xFF000000);//进度轮体颜色
  7. wheel.setContourColor(0xFFFFFFFF);//外圆颜色
  8. wheel.setBarWidth(pxFromDp(ctx,8));//宽度
  9. wheel.setBarLength(pxFromDp(ctx,100));//长度
  10. wheel.setSpinSpeed(2);//旋转速度
  11. wheel.setDelayMillis(3);//间隔时间
  12. }

Library解析

1.功能实现

(1)进度轮绘制。

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

  1. publicProgressWheel(Contextcontext){
  2. super(context);
  3. DrawTasktask=(component,canvas)->{
  4. //初始化元素边界
  5. setupBounds();
  6. //初始化绘制属性
  7. setupPaints();
  8. //绘制内圆
  9. canvas.drawArc(innerCircleBounds,newArc(360,360,false),circlePaint);
  10. //绘制外圆
  11. canvas.drawArc(circleBounds,newArc(360,360,false),rimPaint);
  12. canvas.drawArc(circleOuterContour,newArc(360,360,false),contourPaint);
  13. //绘制条纹
  14. if(isSpinning){
  15. canvas.drawArc(circleBounds,newArc(progress-90,barLength,false),barPaint);
  16. }else{
  17. canvas.drawArc(circleBounds,newArc(-90,progress,false),barPaint);
  18. }
  19. //设置文字于圆心处显示
  20. floattextHeight=textPaint.descent()-textPaint.ascent();
  21. floatverticalTextOffset=(textHeight/2)-textPaint.descent();
  22. for(Stringline:splitText){
  23. floathorizontalTextOffset=textPaint.measureText(line)/2;
  24. canvas.drawText(
  25. textPaint,
  26. line,
  27. (float)component.getWidth()/2-horizontalTextOffset,
  28. (float)component.getHeight()/2+verticalTextOffset);
  29. }
  30. //旋转时在不同的位置画进度条
  31. if(isSpinning){
  32. scheduleRedraw();
  33. }
  34. };
  35. addDrawTask(task);
  36. }

(2)进度轮旋转

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

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

  1. publicvoidstartSpinning(){
  2. isSpinning=true;//设置当前为旋转状态
  3. pinHandler.sendEvent(0);//更新进度
  4. }

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

  1. publicvoidstopSpinning(){
  2. isSpinning=false;//设置当前为停止状态
  3. progress=0;//进度清零
  4. invalidate();
  5. }

(3)进度增加

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

  1. publicvoidincrementProgress(intamount){
  2. isSpinning=false;//增加进度时进度轮不旋转
  3. progress+=amount;//定量增加
  4. if(progress>360){
  5. progress%=360;//超过360会自动重置
  6. }
  7. invalidate();
  8. }

2.移植方法

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

  1. //每次绘制要移动的像素数目
  2. privatefloatspinSpeed=2f;
  3. //绘制过程的时间间隔
  4. privateintdelayMillis=100;
  5. privateEventHandlerspinHandler=newEventHandler(EventRunner.getMainEventRunner())
  6. {
  7. @Override
  8. publicvoidprocessEvent(InnerEventmsg)
  9. {
  10. invalidate();
  11. if(isSpinning)
  12. {
  13. //更新画进度的位置
  14. progress+=spinSpeed;
  15. //要移动的像素数目超过360则重置
  16. if(progress>360)
  17. {
  18. progress=0;
  19. }
  20. spinHandler.sendEvent(0,delayMillis);
  21. }
  22. super.processEvent(msg);
  23. }
  24. };

项目贡献人

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

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件) 鸿蒙 HarmonyOS 应用 第7张

转载请说明出处
知优网 » 鸿蒙开源第三方组件-进度轮ProgressWheel(鸿蒙开发组件)

发表评论

您需要后才能发表评论