Hongmeng open source third-party component migration-loading animation library

Preface

      The loading animation library AVLoadingIndicatorView (https://github.com/81813780/AVLoadingIndicatorView) based on the Android platform has realized the migration and reconstruction of Hongmeng . The code has been open sourced to (https://gitee.com/iscas-ohos/avloading- indicator-view_ohos.git), you are welcome to download and use and provide valuable comments!  

background

        The server sometimes needs to wait for a period of time when loading the data. The loading animation can alleviate the anxiety of the user during the waiting process and make the waiting process more friendly and smooth. AVLoadingIndicatorView is an open source loading animation library, through the call of the animation library, a variety of loading effects can be achieved.

Component function display

    1. Animation

     In the original Android version, there are a total of 28 loading animations in this component library, and the Hongmeng version of the component library successfully implemented 21 animation effects. Due to the lack of API functions of the Hongmeng system, currently 7 animation effects have not been successfully migrated.

#2020征文- Other# Migration of Hongmeng open source third-party components-loading animation library

                                                                                                Figure 1 Schematic diagram of AVLoadingIndicatorView effect

        Figure 1 shows the animation effect display of the AVLoadingIndicatorView of the Hongmeng platform, which can be divided into 6 rows and 4 columns. The corresponding names of the animation effects (from left to right) are as follows:

Row 1

BallPulseIndicator,BallGridPulseIndicator,BallClipRotateIndicator,BallClipRotatePulseIndicator

Row 2      

PacmanIndicator,BallClipRotateMultipleIndicator,       SemiCircleSpinIndicator,BallRotateIndicator

Row 3      

BallScaleIndicator,LineScaleIndicator,LineScalePartyIndicator,BallScaleMultipleIndicator

Row 4      

BallPulseSyncIndicator,BallBeatIndicator,LineScalePulseOutIndicator,LineScalePulseOutRapidIndicator

Row 5      

BallScaleRippleIndicator,BallScaleRippleMultipleIndicator,BallSpinFadeLoaderIndicator,LineSpinFadeLoaderIndicator

Row 6      

BallGridBeatIndicator

       2. Animation control effect

       The AVLoadingIndicatorView component supports the control of the effects of each loading animation. The control types are divided into 4 types: animation start, animation stop, animation display and animation hide. Animation start and animation stop are related to each other, and the two are used to control whether the animation runs; the animation display and the animation hide are related to each other, and the two are used to control whether the animation appears.

#2020征文- Other# Migration of Hongmeng open source third-party components-loading animation library

                                                                                                                    Figure 2 Schematic diagram of four effects control

Sample analysis

       Each animation in this component library has four control effects: start, stop, hide and show. In order to facilitate debugging and demonstration, all animation objects are placed in the same list in Sample, and all animations are controlled to start, stop, hide and display at the same time through four different buttons. The effect is shown in Figure 2.

      The following describes the steps to control all animations to start, stop, hide and show at the same time:

1. Import the AVLoadingIndicatorView class

import com.wang.avi.AVLoadingIndicatorView;

2. Add animation to Layout

      Here you need to add all animations to the Layout, and put the objects of each animation into the same list (that is, the animatorList in the code).

//Take BallPulseIndicator as an example
myLayout.addComponent(ballPulseIndicator);//BallPulseIndicator added to Layout
animatorList.add(ballPulseIndicator);//BallPulseIndicator object into the list
//Take BallGridPulseIndicator as an example
myLayout.addComponent (ballGridPulseIndicator);
animatorList.add(ballGridPulseIndicator);

3. Set four buttons to control all animations to start, stop, hide and show at the same time.

       Take the "start" effect as an example. The startBtn button has a Click listener. When the button is pressed, the startAllAnimator () method will be executed. The startAllAnimator () method uses a for loop to traverse each animation object in the animatorList and call each The start() method of the object achieves the effect of starting the animation.  

//Button monitoring
startBtn.setClickedListener (component-> startAllAnimator (animatorList)); // 启动
endBtn.setClickedListener(component-> stopAllAnimator(animatorList));//停止
hideBtn.setClickedListener(component-> hideAllAnimator(animatorList));//Hide
showBtn.setClickedListener(component-> showAllAnimator(animatorList));//显示
//start
private void startAllAnimator(ArrayList<AVLoadingIndicatorView> avLoadingIndicatorViews){
    for (int i = 0; i < avLoadingIndicatorViews.size(); i++) {
        avLoadingIndicatorViews.get(i).start();//start
    }
}
//stop
private void stopAllAnimator(ArrayList<AVLoadingIndicatorView> avLoadingIndicatorViews){
    for (int i = 0; i < avLoadingIndicatorViews.size(); i++) {
        avLoadingIndicatorViews.get(i).stop();//停止
    }
}
//hide
private void hideAllAnimator(ArrayList<AVLoadingIndicatorView> avLoadingIndicatorViews){
    for (int i = 0; i < avLoadingIndicatorViews.size(); i++) {
        avLoadingIndicatorViews.get (i) .hide (); // 隐藏
    }
}
//show
private void showAllAnimator(ArrayList<AVLoadingIndicatorView> avLoadingIndicatorViews){
    for (int i = 0; i < avLoadingIndicatorViews.size(); i++) {
        avLoadingIndicatorViews.get(i).show();//display
    }
}

Library analysis

1. Function realization

        每个动画效果的绘制都需要执行初始化设置、添加绘画任务、创建动画三个步骤,下面以BallPulseIndicator为例对这三个步骤进行详细介绍。

       (1) 初始化设置 声明setPaint(),setBound(),draw()方法。

public BallPulseIndicator(Context context) {
    super(context);
    Component.DrawTask task = (component, canvas) -> {
        setPaint();//设置画笔
        setBound();//设置动画边界
        draw(canvas,getPaint());//内容绘制
    };
    addDrawTask(task);
}

         (2) 动画绘制 用draw()方法在画布上绘制动画样式。

         由于BallPulseIndicator动画主体是三个圆,第二、第三个圆均是由前一个圆平移得到,因此要设置每两个圆之间的距离,圆的半径大小等属性。

public void draw(Canvas canvas, Paint paint) {
    float circleSpacing=4;  //设置圆之间距离
    float radius=(Math.min(getWidth(),getHeight())-circleSpacing*2)/6;  //设置圆的半径大小
    float x = getWidth()/ 2-(radius*2+circleSpacing);//圆心的x轴坐标
     float y=getHeight() / 2;//圆心的y轴坐标
    for (int i = 0; i < 3; i++) {
        canvas.save();
        float translateX=x+(radius*2)*i+circleSpacing*i;//平移后新圆心的x轴坐标
        canvas.translate(translateX, y);
        canvas.scale(scaleFloats[i], scaleFloats[i]);//缩放效果绘制
        canvas.drawCircle(0, 0, radius, paint);//绘制圆
        canvas.restore();
    }
}

        (3) 动画参数设置

        通过AnimatorValue对动画参数进行具体设置,包括动画的持续时间、重复次数、启动延迟时间、缩放和旋转等(BallPulseIndicator只涉及缩放而无旋转)。

public ArrayList<AnimatorValue> onCreateAnimators() {
    ArrayList<AnimatorValue> animators=new ArrayList<>();
    int[] delays=new int[]{120,240,360};  //设置三个圆的延迟时间
    for (int i = 0; i < 3; i++) {
        final int index=i;
        AnimatorValue scaleAnim=new AnimatorValue();  //值动画
        scaleAnim.setDuration(750);  //动画持续时间
        scaleAnim.setLoopedCount(-1);  //动画无限次重复
        scaleAnim.setDelay(delays[i]);  //每个圆的延迟时间
        addUpdateListener(scaleAnim, (animatorValue, v) -> {
            scaleFloats[index] = v;//控制缩放
            invalidate();//刷新界面
        });
        animators.add(scaleAnim);
    }
    return animators;
}

2. 移植方法

       (1) API直接替换

       在安卓中使用ValueAnimator类设置加载动画的属性,移植之后这些功能主要基于鸿蒙的AnimatorValue类实现。这两个类中的方法名也不同,在进行鸿蒙化迁移时需要根据功能逐一替换。例如:鸿蒙中使用setLoopedCount()方法替换原setRepeatCount()方法来实现动画重复次数的设置。    

       (2) 函数重写    

       鸿蒙的AnimatorValue类相比较于安卓,缺少很多接口,若在实现部分复杂动画时,需要调用这些接口,只能采用函数重写的方法,这也是移植中的主要难点。如安卓中用ValueAnimator.ofFloat(1,0.5f,1)来设置动画的属性值1—0.5f—1的两次变化,实现动画的运行效果,而鸿蒙中缺少该接口,属性值只能在0—1之间单次变化,无法实现动画的完美效果,需要进行功能重写,下面给出此功能重写的代码。

public void onUpdate(AnimatorValue animatorValue, float v) {
    if(v<=0.5f)
        scaleFloats[index] =1-v;
    else
        scaleFloats[index] = v;
    invalidate();
}



The follow-up content of the article and related attachments can click on the original link below to learn the
original link: https://harmonyos.51cto.com/posts/2928#bkwz


To learn more about Hongmeng, please visit:

Hongmeng technology community built by 51CTO and Huawei official strategic cooperation

https://harmonyos.51cto.com/#bkwz


Guess you like

Origin blog.51cto.com/14901125/2605761