目錄:javascript
一、前言java
二、背景git
三、組件效果展現github
五、library解析ide
前言 佈局
基於安卓平臺的連續滾動圖像組件ContinuousScrollableImageView(https://github.com/Cutta/ContinuousScrollableImageView),實現了鴻蒙化遷移和重構,代碼已經開源到(https://gitee.com/isrc_ohos/continuous-scrollable-image-view_ohos),歡迎各位開發者下載使用並提出寶貴意見!post
背景 動畫
ContinuousScrollableImageView_ohos組件經過讓圖像連續滾動,來實現動畫效果。組件支持對圖像的滾動效果進行設置,包括:圖像源、縮放類型、持續時間和方向等。該組件提供動態的視覺效果,能夠用來開發應用的背景等。
組件效果展現
ContinuousScrollableImageView_ohos組件庫中設置了飛機、雲、山三種圖像:飛機的滾動方向設置爲「RIGHT」,向右側滾動;雲和山的滾動方向設置爲「LEFT」,向左滾動。三者組合成一幅完整的、具備連續滾動效果的動畫圖像,如圖1所示。
圖1 ContinuousScrollableImageView_ohos組件運行效果圖
Sample解析
Sample部分主要負責搭建總體的顯示佈局,並實例化飛機、雲、山三種圖像的對象。經過調用Library提供的接口,對三個對象的滾動效果進行屬性設置。想要實現圖1所示的動畫效果,須要如下3個步驟:
步驟1. 導入ContinuousScrollableImageView類。
步驟2. 實例化類對象並設置各個對象的屬性。
步驟3. 將對象添加到總體顯示佈局中。
下面咱們來看一下每一個步驟涉及的詳細操做。
一、導入ContinuousScrollableImageView類
import com.cunoraz.continuousscrollable.ContinuousScrollableImageView;
二、實例化類對象並設置各個對象的屬性
圖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);
三、對象添加到總體顯示佈局中
layout.addComponent(cloud); //飛機對象添加到佈局 layout.addComponent(mountain); //雲對象添加到佈局 layout.addComponent(mountain); //山對象添加到佈局
Library解析
Library向開發者提供ContinuousScrollableImageView類對象的啓動接口和屬性設置接口。以圖1的效果爲例,經過調用啓動接口,可讓飛機、雲和山對象開始滾動;經過調用屬性設置接口,能夠改變上述對象的滾動效果。由Sample部分可知,ContinuousScrollableImageView類對象的屬性設置有兩種方式,本節將揭示,不一樣屬性設置方式下屬性設置接口的功能實現也存在差別。
一、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(); //動畫啓動
二、經常使用方式下屬性設置接口功能實現
飛機和雲採用經常使用方式設置屬性,其屬性包含:滾動週期、滾動方向、圖像源、圖像縮放類型。各接口的功能實現較爲簡單,值得注意的是,在滾動方向和滾動週期功能實現中分別調用了啓動接口,此處是爲了適應下文即將指出的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); }
三、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; } }
項目貢獻人
劉磊 鄭森文 朱偉 陳美汝 王佳思 張馨心