热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

鸿蒙开源第三方组件——进度轮ProgressWheel

目录:1、前言2、背景3、组件功能展示4、Sample解析5、Library解析6、作者系列文章合集前言基于安卓平台的进度轮组件ProgressWheel(https:github

 

目录:
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类似。

鸿蒙开源第三方组件——进度轮ProgressWheel

图1 进度轮旋转

2、进度增加

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

图2 按钮控制进度增加

Sample解析

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

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

鸿蒙开源第三方组件——进度轮ProgressWheel

 图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、背景改变

鸿蒙开源第三方组件——进度轮ProgressWheel

图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  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、样式改变

鸿蒙开源第三方组件——进度轮ProgressWheel

图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


推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
author-avatar
真实的阿凯123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有