天天看點

CircleIndicator元件,使訓示器風格更加多樣化

CircleIndicator元件,使訓示器風格更加多樣化​

UI界面是應用程式可視化必不可少的部分。設計精緻的UI界面可以使得整個可視化應用程式給使用者留下深刻的印象,是改善使用者界面體驗最直接的方式。

ArkUI開發架構為開發者提供了豐富的UI原生元件,如Navigation(Page頁面的根容器)、ScrollBar(滾動條元件)、Swiper(滑動容器)及Tabs(通過頁簽進行内容視圖切換的容器元件)等。其中,Swiper元件和Tabs元件在應用程式開發中對于訓示器的使用引入較多,但是直接使用原生的Swiper元件和Tabs元件不适用于表現複雜的UI訓示器互動變化。是以,我們針對Swiper元件和Tabs元件在訓示器應用方向做了一個簡單的封裝,以CiecleIndicator三方元件的形式提供應用程式依賴使用,進而提升了ArkUI開發架構的UI界面之訓示器風格多樣化的能力。

CircleIndicator介紹​

CircleIndicator元件UI效果展示

圓形訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

長條訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

橫幅訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

三角訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

圖示訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

攜帶中央視圖的Tabs訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

固定位置Tabs訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

​固定位置Tabs訓示器(膠囊風格):

CircleIndicator元件,使訓示器風格更加多樣化

​固定位置Tabs訓示器(攜帶角标):

CircleIndicator元件,使訓示器風格更加多樣化

可滑動Tabs訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

可滑動Tabs訓示器(水滴滑塊):

CircleIndicator元件,使訓示器風格更加多樣化

可滑動Tabs訓示器(首列固定):

CircleIndicator元件,使訓示器風格更加多樣化

titles訓示器:

CircleIndicator元件,使訓示器風格更加多樣化

什麼是CircleIndicator?

CircleIndicator顧名思義,它指的是圓形訓示器。不過在我們OpenHarmony三方元件中的CircleIndicator元件不再是狹義的圓形訓示器,而是将多種表現形式的訓示器彙集為一體的歸一化訓示器合集元件。

CircleIndicator的源碼實作

這裡我們以CircleIndicator元件源碼中的TriangularIndicator.ets檔案為源碼解析樣例對象展開分析。首先建立TriangularIndicator.ets檔案,使用命名空間建立TriangularIndicator初始化模型:

namespace TriangularIndicator {
  export class Model {
//設定訓示器高度
    mHeight: number = 18
//設定訓示器寬度
    mWidth: number = lpx2px(720)
//設定訓示器背景色
    mBackgroundColor: string
//字段過多,此處進行省略
//各字段set與get方法,此處隻以height字段為例
    public getHeight(): number {
      return this.mHeight
    }
    public setHeight(height: number): Model {
      this.mHeight = height
      return this
    }
    //觸摸事件攔截
    onPageTouch: (event: TouchEvent, currentIndicator: number) => void
    public notifyTouch(event: TouchEvent, currentIndex: number) {
      this.onPageTouch(event, currentIndex)
    }
    //設定構造器
    private tabsController: TabsController
        (tabsController: TabsController) {
      this.tabsController = tabsController
    }
    //頁面切換監聽
    indexChange: (itemIndex: number) => void
    public setChangeListener(callback: (index: number) => void): Model{
      this.indexChange = callback
      return this
    }
}      

将TriangularIndicator應用元件化:

@Component
struct TriangularIndicator {
//擷取TriangularIndicator執行個體
  @State model: TriangularIndicator.Model = new TriangularIndicator.Model(null)
//初始化訓示器目前index
  @Link @Watch("itemIndexChange") itemIndex: number
//設定訓示器總條數
  @State count: number = 0
//再分别實作itemIndexChange、aboutToAppear、onTouch、getOffset方法,此處實作不做展示
//再在build方法裡面描述UI結構
    build() {
      Column() {
        Rect({ width: this.model.mWidth, height:     this.model.mLineHeight }).fill(this.model.mLineColor)
        Polygon()
          .points(this.model.mReverse ?
        [[px2vp(this.model.mWidth) / (this.count * 2) - this.model.mTriangleWidth / 2, this.model.mLineHeight - this.model.mYOffset],
        [px2vp(this.model.mWidth) / (this.count * 2), this.model.mLineHeight + this.model.mTriangleHeight - this.model.mYOffset],
        [px2vp(this.model.mWidth) / (this.count * 2) + this.model.mTriangleWidth / 2, this.model.mLineHeight - this.model.mYOffset]] :
        [[px2vp(this.model.mWidth) / (this.count * 2) - this.model.mTriangleWidth / 2, -this.model.mYOffset],
  [px2vp(this.model.mWidth) / (this.count * 2), -this.model.mTriangleHeight - this.model.mYOffset],
        [px2vp(this.model.mWidth) / (this.count * 2) + this.model.mTriangleWidth / 2, -this.model.mYOffset]])
          .offset(this.model.mStartInterpolator ?
            { x: px2vp(this.model.mWidth) / this.count * (this.itemIndex -     this.model.mStartInterpolator.interpolate(Math.abs(this.model.offs    et / this.model.mWidth)) * Math.sign(this.model.offset)),
              y: 0 } :
            { x: px2vp(this.model.mWidth) / this.count * (this.itemIndex - this.model.offset / this.model.mWidth),
              y: 0 })
          .fill(this.model.mLineColor)
          .height(this.model.mHeight)
          .width(this.model.mWidth)
      }.width('100%').height(this.model.mHeight)
      .backgroundColor(this.model.mBackgroundColor)
    }
}      

最後将TriangularIndicator暴露出來供外部引用:

export default TriangularIndicator      

CircleIndicator實戰​

建立項目

如圖所示,在DevEco Studio中建立CircleIndicator_Test項目,項目類型選擇Application,語言選擇eTS,點選Finish完成建立。

CircleIndicator元件,使訓示器風格更加多樣化

建立工程

添加依賴

成功建立項目後,接下來就是将CircleIndicator元件下載下傳至項目中。請在添加依賴之前參考如何安裝OpenHarmony npm包(https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_npm_usage.md)完成OpenHarmony npm環境配置。完成OpenHarmony npm環境配置之後,在DevEco Studio的底部導航欄,點選“Terminal”(快捷鍵Alt+F12), 鍵入指令:npm install @ohos/circle-indicator --save并回車,此時CircleIndicator元件會自動下載下傳至項目中。下載下傳完成後工程根目錄下會生成node_modules/@ohos/CircleIndicator目錄。

編寫邏輯代碼

提供多種Indicator,使用方法類似,以TriangularIndicator為例

1. 初始化:執行個體化TabsController和對應的Indicator.Model 對象, 并添加number類型成員以記錄目前頁下标

private controller: TabsController = new TabsController()
@State model: TriangularIndicator.Model = new TriangularIndicator.Model(this.controller)
@State itemIndex: number = 0      

2. 屬性設定:通過Model類對象設定UI屬性來自定義所需風格,也可以添加所需的回調

aboutToAppear() {
  this.model
    .setReverse(true)
    .setLineHeight(4)
    .setTriangleHeight(10)
    .setLineColor("#e94220")
    .setBackgroundColor("#eeeeee")
    .setChangeListener((itemIndex) => {
      console.info("change page to " + this.data[itemIndex])
    })
}      

3. 界面繪制:在Tabs元件旁放置Indicator元件,注意需要關閉原生的bar。并監聽Tabs元件的touch事件,通知給Model類,以統一處理滑動邏輯

build() {
  Column() {
    TriangularIndicator({ itemIndex: $itemIndex, count: this.data.length, model: this.model })
    Tabs({ index: this.itemIndex, controller: this.controller }) {
      ……
    }
    .barWidth(0)
    .onTouch((event: TouchEvent) => {
      this.model.notifyTouch(event, this.itemIndex)
    })
  }.padding({ top: 40 })
  .backgroundColor("#eeeeee")
}