鴻蒙開源第三方元件——連續滾動影像元件

HarmonyOS技術社群發表於2021-04-28

目錄:

1、前言

2、背景

3、元件效果展示

4、sample解析

5、library解析

6、《鴻蒙開源第三方元件》系列文章合集

前言

        基於安卓平臺的連續滾動影像元件ContinuousScrollableImageView(https://github.com/Cutta/ContinuousScrollableImageView),實現了鴻蒙化遷移和重構,程式碼已經開源到(https://gitee.com/isrc_ohos/continuous-scrollable-image-view_ohos),歡迎各位開發者下載使用並提出寶貴意見!

背景

       ContinuousScrollableImageView_ohos元件通過讓影像連續滾動,來實現動畫效果。元件支援對影像的滾動效果進行設定,包括:影像源、縮放型別、持續時間和方向等。該元件提供動態的視覺效果,可以用來開發應用的背景等。

元件效果展示

       ContinuousScrollableImageView_ohos元件庫中設定了飛機、雲、山三種影像:飛機的滾動方向設定為“RIGHT”,向右側滾動;雲和山的滾動方向設定為“LEFT”,向左滾動。三者組合成一幅完整的、具有連續滾動效果的動畫影像,如圖1所示。

鴻蒙開源第三方元件——連續滾動影像元件

圖1  ContinuousScrollableImageView_ohos元件執行效果圖

Sample解析

       Sample部分主要負責搭建整體的顯示佈局,並例項化飛機、雲、山三種影像的物件。通過呼叫Library提供的介面,對三個物件的滾動效果進行屬性設定。想要實現圖1所示的動畫效果,需要以下3個步驟:

步驟1. 匯入ContinuousScrollableImageView類。

步驟2. 例項化類物件並設定各個物件的屬性。

步驟3. 將物件新增到整體顯示佈局中。

下面我們來看一下每個步驟涉及的詳細操作。

1、匯入ContinuousScrollableImageView類

import com.cunoraz.continuousscrollable.ContinuousScrollableImageView;

 

2、例項化類物件並設定各個物件的屬性

       圖1中的動畫效果需要例項化3個ContinuousScrollableImageView物件分別代指包含飛機、雲、山三種影像。

       設定各物件屬性的方式有兩種:常用方式和Builder方式。常用方式是指通過物件單獨呼叫類介面的方式;Builder方式即建造者模式。使用者可根據個人需要,自行確定使用哪種方式設定物件屬性。此處為了證明兩種方式的有效性,飛機和雲影像採用常用方式設定屬性,山影像採用Builder方式設定屬性。                          ContinuousScrollableImageView物件的可設定屬性有4個,包括:滾動方向、滾動週期、縮放型別、影像源。

(1)例項化飛機影像的物件並進行屬性設定

// 例項化物件
ContinuousScrollableImageView plane=new ContinuousScrollableImageView(this);
// 採用常用方式進行屬性設定
LayoutConfig planeConfig=new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,0,LayoutConfig.UNSPECIFIED_ALIGNMENT,1);
plane.setLayoutConfig(planeConfig);
plane.setDirection(ContinuousScrollableImageView.RIGHT);  //設定滾動方向向右
plane.setDuration(2500);   //設定滾動週期
plane.setScaleType(ContinuousScrollableImageView.CENTER_INSIDE);  //設定縮放型別
plane.setResourceId(ResourceTable.Media_plane);  // 設定影像源

(2)例項化雲影像的物件並進行屬性設定

// 例項化物件
ContinuousScrollableImageView cloud=new ContinuousScrollableImageView(this);
// 採用常用方法進行屬性設定
LayoutConfig cloudConfig=new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,0,LayoutConfig.UNSPECIFIED_ALIGNMENT,1);
cloud.setLayoutConfig(cloudConfig);
cloud.setDirection(ContinuousScrollableImageView.LEFT);   //設定滾動方向向左
cloud.setDuration(4000);    //設定滾動週期
cloud.setResourceId(ResourceTable.Media_cloud);    //設定影像源

 (3)例項化山影像的物件並進行屬性設定

LayoutConfig mountainConfig=new LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,0,LayoutConfig.UNSPECIFIED_ALIGNMENT,1);
//採用Builder方式進行物件建立和屬性設定
ContinuousScrollableImageView mountain=new ContinuousScrollableImageView.Builder(this.getAbility())
        .setDirection(ContinuousScrollableImageView.LEFT)    //設定方向向左
        .setDuration(6000)    //設定時間間隔
        .setResourceId(ResourceTable.Media_mountain)    //設定影像源
        .build();
mountain.setLayoutConfig(mountainConfig);

3、物件新增到整體顯示佈局中

layout.addComponent(cloud); //飛機物件新增到佈局
layout.addComponent(mountain); //雲物件新增到佈局
layout.addComponent(mountain);  //山物件新增到佈局

Library解析

       Library向開發者提供ContinuousScrollableImageView類物件的啟動介面和屬性設定介面。以圖1的效果為例,通過呼叫啟動介面,可以讓飛機、雲和山物件開始滾動;通過呼叫屬性設定介面,可以改變上述物件的滾動效果。由Sample部分可知,ContinuousScrollableImageView類物件的屬性設定有兩種方式,本節將揭示,不同屬性設定方式下屬性設定介面的功能實現也存在差異。

1、ContinuousScrollableImageView類物件啟動介面

      該介面的功能實現內容較多,但主要邏輯較為清晰,主要可以分為四個部分:設定佈局、建立數值動畫、對不同的滾動方向設定監聽和啟動動畫。

(1)設定佈局

 鴻蒙開源第三方元件——連續滾動影像元件

圖2 兩個佈局依次出現

       如圖2所示,畫面中所有的ContinuousScrollableImageView類物件都需要具有迴圈滾動的效果,以飛機為例:飛機滾動至最右側時,逐漸顯示的部分需要在最左側重新出現。為此,設計了兩個佈局:firstImage和secondImage,二者佈局相同且迴圈顯示,其中一個佈局顯示另一個佈局消失的部分。

private void setImages() {
    ......
    firstImage = (Image) this.findComponentById(ResourceTable.Id_first_image);
    secondImage = (Image) this.findComponentById(ResourceTable.Id_second_image);
    firstImage.setImageAndDecodeBounds(resourceId);
    secondImage.setImageAndDecodeBounds(resourceId);
    setScaleType(scaleType);
}

 (2)建立數值動畫

       飛機、雲和山都是靜態的,想讓實現滾動效果,需要藉助動畫類。此處採用的是數值動畫的方式,來啟動各物件。同時還需要設定動畫的迴圈次數、線性變化、迴圈週期等屬性。

animator.setLoopedCount(AnimatorValue.INFINITE);  //動畫無限重複
animator.setCurveType(Animator.CurveType.LINEAR);  //動畫線性變化
animator.setDuration(duration);   //動畫的持續時間

 (3)對不同的滾動方向設定監聽

      飛機、雲和山都可以設定不同的滾動方向,針對不同的方向設定不同的值動畫監聽,以飛機為例:當飛機橫向滾動時,通過設定firstImage和secondImage的橫座標變化,達到二者迴圈顯示的目的。當飛機豎向滾動動,通過設定firstImage和secondImage的座標變化,達到二者迴圈顯示的目的。

switch (DEFAULT_ASYMPTOTE) {
    case HORIZONTAL:   // 橫向滾動
        animator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {       //值動畫監聽
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                // firstImage和secondImage迴圈顯示演算法
                float progress;
                if (DIRECTION_MULTIPLIER == 1)
                    progress = DIRECTION_MULTIPLIER * (v);
                else
                    progress = DIRECTION_MULTIPLIER * (-v);
                float width = DIRECTION_MULTIPLIER * (-firstImage.getWidth());
                float translationX = width * progress;
                firstImage.setTranslationX(translationX);  //設定firstImage的橫座標
                secondImage.setTranslationX(translationX - width); //設定secondImage的橫座標
            }
        });
        break;
......

(4)啟動動畫

      動畫啟動後,飛機、雲和山的座標就會發生變化,此時他們的動畫效果就由靜態的變成滾動的。

animator.start();      //動畫啟動

 

 2、常用方式下屬性設定介面功能實現

      飛機和雲採用常用方式設定屬性,其屬性包含:滾動週期、滾動方向、影像源、影像縮放型別。各介面的功能實現較為簡單,值得注意的是,在滾動方向和滾動週期功能實現中分別呼叫了啟動介面,此處是為了適應下文即將指出的Builder方式,具體原因將在下文講述。若開發者只採用常用方式進行屬性設定,可以將啟動介面從滾動方向和滾動週期功能實現中分離出來,通過飛機或者雲的物件單獨呼叫。

//設定滾動週期
public void setDuration(int duration) {
    this.duration = duration;
    isBuilt = false;
    build();
}
//設定方向
public void setDirection(@Directions int direction) {
    this.direction = direction;
    isBuilt = false;
    setDirectionFlags(direction);
    build();
}
//設定影像源
public void setResourceId(int resourceId) {
    this.resourceId = resourceId;
    firstImage.setImageAndDecodeBounds(this.resourceId);
    secondImage.setImageAndDecodeBounds(this.resourceId);
}
//設定影像縮放型別
public void setScaleType(@ScaleType int scaleType) {
    if (firstImage == null || secondImage == null) {
        throw new NullPointerException();
    }
    Image.ScaleMode type = Image.ScaleMode.CENTER;
    switch (scaleType) {
	···
    }
    this.scaleType = scaleType;
    firstImage.setScaleMode(type);
    secondImage.setScaleMode(type);
}

 3、Builder方式設定屬性

       對山採用Builder方式進行屬性設定,各屬性在功能實現時分別呼叫了常用方式下的屬性設定介面,但是缺少啟動介面的呼叫。

      為了在Builder方式下也能正常啟動動畫,常用方式下的滾動方向和滾動週期功能實現中包含了啟動介面,這樣當在Builder方式下呼叫上述介面時,就可以實現動畫的啟動。

public static final class Builder {
    private ContinuousScrollableImageView scrollableImage;
    public Builder(Ability ability) {
        scrollableImage = new ContinuousScrollableImageView(ability);
    }
    //設定滾動週期
    public Builder setDuration(int duration) {
        scrollableImage.setDuration(duration);
        return this;
    }
    //設定影像源
    public Builder setResourceId(int resourceId) {
        scrollableImage.setResourceId(resourceId);
        return this;
    }
   //設定滾動方向
    public Builder setDirection(@Directions int direction) {
        scrollableImage.setDirection(direction);
        return this;
    }
    //設定縮放型別
    public Builder setScaleType(@ScaleType int scaleType) {
        scrollableImage.setScaleType(scaleType);
        return this;
    }
    public ContinuousScrollableImageView build() {
        return scrollableImage;
    }
}

專案貢獻人

劉磊 鄭森文 朱偉 陳美汝 王佳思 張馨心

 

作者:朱偉ISRC
想了解更多內容,請訪問51CTO和華為合作共建的鴻蒙社群:https://harmonyos.51cto.com

相關文章