DEV Community

Cover image for HarmonyOS development: Packaging and use of the Banner component of the carousel graph
程序员一鸣
程序员一鸣

Posted on

HarmonyOS development: Packaging and use of the Banner component of the carousel graph

Foreword

this article is based on Api12 

the carousel diagram is very common in every project. The Swiper component is also provided in the container component of Hongmeng Zhongzhong, which is used for sliding carousel display of sub-components. It is the same as the use of the front end. Let's look at the basic usage first.

 

Swiper() {
          ForEach(["1", "2", "3", "4", "5", "6"], (item: string) => {
            Text(item.toString())
              .width('90%')
              .height(160)
              .backgroundColor(0xAFEEEE)
              .textAlign(TextAlign.Center)
              .fontSize(30)
          }, (item: string) => item)
        }
Enter fullscreen mode Exit fullscreen mode

The above code can easily realize a carousel effect. Of course, it is only a simple case. Many attributes are not set. According to normal use, there is really no need to do any encapsulation. However, there is a potential problem that needs encapsulation. For example, when using lazy loading data, if there is no encapsulation, a large number of codes need to be repeated for each carousel, this is obviously redundant; There is another scenario, that is, the carousel of the system cannot meet our needs. In this case, it has to be encapsulated. 

The general content of this article is as follows: 

1. Code and effect display after simple encapsulation

2. Lazy loading data and common data encapsulation based on Swiper

3. Open source address

4. Relevant summary

first, the code and effect display after simple encapsulation

the encapsulated Banner has been uploaded to the remote warehouse and is very simple to use. 

Way one : in the Terminal window, run the following command to install the third-party package. DevEco Studio automatically adds the third-party package dependency to the project oh-package.json5.

 

ohpm install @abner/banner
Enter fullscreen mode Exit fullscreen mode

Way two: set the three-party package dependency in the oh-package.json5 of the project. The configuration example is as follows:

"dependencies": { "@abner/banner": "^1.0.2"}
Enter fullscreen mode Exit fullscreen mode

There is nothing to say about the effect, it is all encapsulated by Swiper component. 

Image description

Code implementation, after all, to take the package, simplify a lot of code, a simple case is as follows:

 

Banner({
          data: ["1", "2", "3", "4", "5", "6"],
          itemPage: this.itemPage
       })
Enter fullscreen mode Exit fullscreen mode

for more cases, don't post them, just look at the open source address in item 3.

Related property configuration

property type overview
data  Array data Source 
itemPage  (index: number, item: Object)  banner corresponding page 
onChange  callback function  entry switch listening 
bannerHeight  Length  banner height 
bannerWidth  Length  banner width 
autoPlay  boolean  whether to automatically play, default false 
interval  number Default 3-second carousel 
disableSwipe  boolean  whether sliding is prohibited 
itemSpace  number  clearance between subassemblies 
currentIndex  number  selected, default 0th 
indicator  DotIndicator DigitIndicator
isLineIndicator  boolean  whether it is a custom line indicator 
indicatorType  IndicatorType  indicator position 
lineIndicatorWidth  number  line Indicator Width 
lineIndicatorHeight  number  line indicator height 
lineIndicatorBgColor ResourceColor Line Indicator Background 
lineMargin Margin Length
isLoop boolean whether to enable a loop. The default is a loop. 
indicatorRules Record<string, Record<string, string VerticalAlign
isLazyData boolean whether to use data lazy loading 
lazyCachedCount number number of cache entries, default is 1 
onLazyDataSource (dataSource: BannerDataSource) callback function, used to control the addition and deletion of data

二、Lazy loading data and common data encapsulation based on Swiper

First, the subcomponents of Swiper support ForEach and LazyForEach for rendering data. LazyForEach is the data lazy loading mode, which is also the default recommend mode in official cases. When the component slides out of the visible area, the framework will destroy and recycle the component to reduce memory usage. However, the two rendering data are completely different in code logic. 

ForEach is relatively simple, the data source is an array, and the encapsulation is also very simple:

 

Swiper(this.swiperController) {
        ForEach(this.data, (item: Object, index: number) => {
          this.itemPage(index, item)
        })
      }
Enter fullscreen mode Exit fullscreen mode

the LazyForEach mode is relatively complicated to use. The creation of components includes two situations: the first rendering of LazyForEach and the non-first rendering of LazyForEach, which need to be considered. 

For ForEach data loading, we only consider the changes of the data source, but in LazyForEach, we must use the DataChangeListener object to update, we need to create a new object, implement IDataSource, and add, delete, modify and query data.

 

/**
 * AUTHOR:AbnerMing
 * DATE:2024/2/23
 * INTRODUCE:
 * */
export class BannerDataSource implements IDataSource {
  private listeners: DataChangeListener[] = []
  private originDataArray: Object[] = []

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  totalCount(): number {
    return this.originDataArray.length
  }

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  getData(index: number): Object {
    return [this.originDataArray[index]]
  }

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener);
    }
  }

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      this.listeners.splice(pos, 1);
    }
  }


  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }


  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }


  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }


  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }


  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }


  public addData(index: number, data: Object): void {
    this.originDataArray.splice(index, 0, data);
    this.notifyDataAdd(index);
  }


  public pushData(data: Object): void {
    this.originDataArray.push(data);
    this.notifyDataAdd(this.originDataArray.length - 1);
  }


  public deleteData(index: number): void {
    this.originDataArray.splice(index, 1);
    this.notifyDataDelete(index);
  }


  public moveData(from: number, to: number): void {
    let temp: Object = this.originDataArray[from];
    this.originDataArray[from] = this.originDataArray[to];
    this.originDataArray[to] = temp;
    this.notifyDataMove(from, to);
  }

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  public changeData(index: number, data: Object): void {
    this.originDataArray.splice(index, 1, data);
    this.notifyDataChange(index);
  }


  public reloadData(): void {
    this.notifyDataReload();
  }

}
Enter fullscreen mode Exit fullscreen mode

After the above encapsulation, attention should be paid to the use, that is, when updating the data: 

declare variables:

 

@State bannerDataSource: BannerDataSource = new BannerDataSource()
Enter fullscreen mode Exit fullscreen mode

assignment variable:

 

Banner({
          data: ["1", "2", "3", "4", "5", "6"],
          itemPage: this.itemPage,
          onLazyDataSource: (dataSource: BannerDataSource) => {
            this.bannerDataSource=dataSource
          }
        })
Enter fullscreen mode Exit fullscreen mode

behavior Action:

 

this.bannerDataSource.pushData()
this.bannerDataSource.deleteData()
Enter fullscreen mode Exit fullscreen mode

third, open source address

in the open source address, the use of each case is also introduced. 

https://ohpm.openharmony.cn/#/cn/detail/@abner%2Fbanner 

IV. Relevant Summary

At present, the carousel map only makes a simple package for Swiper and adds a line indicator, which is far from enough. After all, there are many kinds of Carousel graphics in daily life, and the indicators are also strange, and the follow-up will continue to expand on this basis.

Top comments (0)