鴻蒙開源第三方組件的遷移——加載動畫庫

前言java

      基於安卓平臺的加載動畫庫AVLoadingIndicatorView(https://github.com/81813780/AVLoadingIndicatorView),實現了鴻蒙化遷移和重構,代碼已經開源到(https://gitee.com/iscas-ohos/avloading-indicator-view_ohos.git),歡迎各位下載使用並提出寶貴意見!  git

背景github

        服務器在加載數據的時候有時須要等待一段時間,加載動畫能夠緩解用戶等待過程當中的焦慮情緒,使等待過程變得更加友好、流暢。AVLoadingIndicatorView是一個開源的加載動畫庫,經過動畫庫的調用,能夠實現各類各樣的加載效果。canvas

組件功能展現api

    1. 動畫效果服務器

     在原Android版本中,本組件庫裏共有28個加載動畫,鴻蒙版本的組件庫成功實現其中21種動畫效果。因爲鴻蒙系統部分API功能缺失,目前有7個動畫效果未成功遷移。ide

#2020徵文-其它#鴻蒙開源第三方組件的遷移——加載動畫庫

                                                                                                圖1 AVLoadingIndicatorView效果示意圖函數

        圖1所示爲鴻蒙平臺的AVLoadingIndicatorView的動畫效果展現,可分爲6行4列,動畫效果的對應名稱(從左至右)以下:oop

Row 1post

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. 動畫控制效果

       AVLoadingIndicatorView組件支持對各加載動畫的效果進行控制,控制類型分爲4種:動畫啓動、動畫中止、動畫顯示和動畫隱藏。動畫啓動和動畫中止相互關聯,兩者用於控制動畫是否運行;動畫顯示和動畫隱藏相互關聯,兩者用於控制動畫是否出現,控制效果如圖2所示。

#2020徵文-其它#鴻蒙開源第三方組件的遷移——加載動畫庫

                                                                                                                    圖2 四種效果控制示意圖

Sample解析

       本組件庫中的每一個動畫都有啓動、中止、隱藏和顯示四種控制效果。爲了方便調試和演示,Sample中將全部動畫的對象放入同一個list,經過四個不一樣的按鈕,控制全部動畫同時啓動、中止、隱藏和顯示,效果如圖2所示。

      下面介紹控制全部動畫同時啓動、中止、隱藏和顯示的步驟:

一、導入AVLoadingIndicatorView類

import com.wang.avi.AVLoadingIndicatorView;

二、動畫添加到Layout

      此處須要將全部動畫添加到Layout中,並將各動畫的對象放入同一list(即代碼中的animatorList)。

//以BallPulseIndicator爲例
myLayout.addComponent(ballPulseIndicator);//BallPulseIndicator添加到Layout
animatorList.add(ballPulseIndicator);//BallPulseIndicator對象放入list
//以BallGridPulseIndicator爲例
myLayout.addComponent(ballGridPulseIndicator);
animatorList.add(ballGridPulseIndicator);

三、設置四個按鈕,用以控制全部動畫同時啓動、中止、隱藏和顯示。

       以"啓動"效果爲例,startBtn按鈕設置了Click監聽,按下按鈕時,會執行startAllAnimator ()方法,startAllAnimator ()方法中藉助for循環,遍歷animatorList中的每個動畫的對象,並調用每一個對象的start()方法,達到動畫啓動的效果。  

//按鈕監聽
startBtn.setClickedListener(component-> startAllAnimator(animatorList));//啓動
endBtn.setClickedListener(component-> stopAllAnimator(animatorList));//中止
hideBtn.setClickedListener(component-> hideAllAnimator(animatorList));//隱藏
showBtn.setClickedListener(component-> showAllAnimator(animatorList));//顯示
//start
private void startAllAnimator(ArrayList<AVLoadingIndicatorView> avLoadingIndicatorViews){
    for (int i = 0; i < avLoadingIndicatorViews.size(); i++) {
        avLoadingIndicatorViews.get(i).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();//顯示
    }
}

Library解析

1. 功能實現

        每一個動畫效果的繪製都須要執行初始化設置、添加繪畫任務、建立動畫三個步驟,下面以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動畫主體是三個圓,第2、第三個圓均是由前一個圓平移獲得,所以要設置每兩個圓之間的距離,圓的半徑大小等屬性。

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();
}



文章後續內容和相關附件能夠點擊下面的原文連接前往學習
原文連接:https://harmonyos.51cto.com/posts/2928#bkwz


想了解更多關於鴻蒙的內容,請訪問:

51CTO和華爲官方戰略合做共建的鴻蒙技術社區

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

相關文章
相關標籤/搜索