鸿蒙开发 ——UI开发之banner库

📑往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

✒️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✒️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✒️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✒️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✒️ 记录一场鸿蒙开发岗位面试经历~

✒️ 持续更新中……


简介

本项目是适配OpenHarmony环境的一款banner库,常用于广告图片轮播场景,基于Swiper进行封装,能力如下:

  • 支持自动轮播。
  • 支持无限轮播。
  • 支持垂直轮播。
  • 支持自定义指示器。
  • 支持定制的翻页动画效果,目前动画只支持8种动效,无法做到不同动效叠加。

Swiper组件能力和Banner组件能力对比:

能力列表Swiper组件Banner组件
自动轮播支持支持
无限轮播支持支持
垂直轮播支持支持
自定义指示器部分支持支持
指示器和banner分离不支持支持
定制翻页动画效果不支持支持

ohpm install @ohos/banner

使用说明

1.提供了自定义轮播组件Banner以及自定义指示器CircleIndicator、PixelMapIndicator、RectFIndicator、RoundLinesIndicator组件。

2.以自定义轮播组件Banner和自定义指示器CircleIndicator举例:

import { Banner,BannerOptions,AnimatedEnum,IndicatorConfig, CircleIndicator,SwiperIndicator,IData,BannerMargin,AnimatedConfig } from '@ohos/banner'

export class Data implements IData{
  str:string = '';
}

@Entry
@ComponentV2
struct BannerSamplePage {
  private swiperController: SwiperController = new SwiperController()
  private touTiaoSwiperController: SwiperController = new SwiperController()
  @Local data: IData[] = []

  @Local indicatorConfig: IndicatorConfig = new IndicatorConfig(10, 0, '#5CB85C', '#FFFFFF')
  @Local bannerSize:number = 10;

  @Local autoPlay?:boolean = true // 自定播放
  @Local indicator?:SwiperIndicator = { bool:false } // 系统的指示器配置 不启用设置false
  @Local loop?:boolean = true // 是否开启循环
  @Local vertical?:boolean = false // 是否纵向滑动

  @Local interval?:number = 3000 // 当前item停滞时间
  @Local duration?:number = 800 // 子组件切换动画时长
  @Local bannerMargin:BannerMargin = {left:40, right:40};// 水平是左右的margin,垂直为上下的margin

  @Local animatedEnum?:AnimatedEnum = AnimatedEnum.MZScaleIn// 魅族 动画效果

  animatedSelect:number | number[] = 0
  animatedSupports:AnimatedEnum[] = [
    AnimatedEnum.NonePage,
    AnimatedEnum.AlphaPage,
    AnimatedEnum.DepthPage,
    AnimatedEnum.MZScaleIn ,
    AnimatedEnum.RotateDownPage ,
    AnimatedEnum.RotateUpPage,
    AnimatedEnum.RotateY ,
    AnimatedEnum.ScaleIn ,
    AnimatedEnum.ZoomOutPage
  ]
  animatedTypes:string[] = [
    'NonePage',
    'AlphaPage',
    'DepthPage',
    'MZScaleIn' ,
    'RotateDownPage' ,
    'RotateUpPage',
    'RotateY' ,
    'ScaleIn' ,
    'ZoomOutPage'
  ]

  @Local currentPos1:number = 0

  @Local curve?:Curve = Curve.Linear // 动画曲率

  @Local bannerOptions:BannerOptions = {
    swiperController: this.swiperController,
    autoPlay:this.autoPlay, // 自定播放
    interval:this.interval, // 当前item停滞时间
    indicator:this.indicator, // 系统的指示器配置 不启用设置false
    loop:this.loop, // 是否开启循环
    duration:this.duration, // 子组件切换动画时长
    vertical:this.vertical, // 是否纵向滑动
    curve:Curve.Linear, // 动画曲率

    bannerMargin: {left:this.bannerMargin.left, right:this.bannerMargin.right},// 水平是左右的margin,垂直为上下的margin
    animatedEnum: AnimatedEnum.ZoomOutPage,// 动画效果

    onChange: (index:number)=>{
      console.log('dodo BannerConfigPage onChange 当前页面index='+index)
      this.indicatorConfig.setCurrentPosition(index)
      this.itemIndex = index;
    },

    onGestureSwipe:(index: number, extraInfo: SwiperAnimationEvent)=>{
      console.log('dodo BannerConfigPage onGestureSwipe 当前页面index='+index + ' extraInfo='+JSON.stringify(extraInfo))
    },

    onAnimationStart:(index: number, targetIndex: number, extraInfo: SwiperAnimationEvent)=>{
      console.log('dodo BannerConfigPage onAnimationStart 当前页面index='+index + '   targetIndex='+targetIndex + ' extraInfo='+JSON.stringify(extraInfo))
    },

    onAnimationEnd:(index: number, extraInfo: SwiperAnimationEvent)=>{
      console.log('dodo BannerConfigPage onAnimationStart 当前页面index='+index +  ' extraInfo='+JSON.stringify(extraInfo))
    }
  }
  aboutToDisappear() {

  }

  @Local itemIndex: number = 0

  aboutToAppear(): void {
    this.createNewDataList();
  }

  createNewDataList(){
    let list = new Array<IData>()
    for (let i = 1; i <= this.bannerSize; i++) {
      let data = new Data();
      data.str = '数字'+i.toString()
      list.push(data)
    }
    this.data = list
    this.indicatorConfig.setIndicatorSize(this.data.length)
  }

  createNewBannerConfig(){
    this.bannerOptions = {
      swiperController: this.swiperController,
      autoPlay:this.autoPlay, // 自定播放
      interval:this.interval, // 当前item停滞时间
      indicator:this.indicator, // 系统的指示器配置 不启用设置false
      loop:this.loop, // 是否开启循环
      duration:this.duration, // 子组件切换动画时长
      vertical:this.vertical, // 是否纵向滑动
      curve:Curve.Linear, // 动画曲率

      bannerMargin: {left:this.bannerMargin.left, right:this.bannerMargin.right},// 水平是左右的margin,垂直为上下的margin
      animatedEnum: this.animatedSupports[this.animatedSelect as number],// 动画效果

      onChange: (index:number)=>{
        console.log('dodo BannerConfigPage onChange 当前页面index='+index)
        this.indicatorConfig.setCurrentPosition(index)
        this.itemIndex = index;
      },

      onGestureSwipe:(index: number, extraInfo: SwiperAnimationEvent)=>{
        console.log('dodo BannerConfigPage onGestureSwipe 当前页面index='+index + ' extraInfo='+JSON.stringify(extraInfo))
      },

      onAnimationStart:(index: number, targetIndex: number, extraInfo: SwiperAnimationEvent)=>{
        console.log('dodo BannerConfigPage onAnimationStart 当前页面index='+index + '   targetIndex='+targetIndex + ' extraInfo='+JSON.stringify(extraInfo))
      },

      onAnimationEnd:(index: number, extraInfo: SwiperAnimationEvent)=>{
        console.log('dodo BannerConfigPage onAnimationStart 当前页面index='+index +  ' extraInfo='+JSON.stringify(extraInfo))
      }
    }
  }

  // Banner页面内容设置,可自定义任意内容
  BACKGROUND_COLORS = [Color.Red, Color.Orange,  Color.Pink, Color.Grey]
  IMAGE_RESOURCES = [$r('app.media.jpg1'),$r('app.media.jpg2'),$r('app.media.png3'),$r('app.media.webp5')]

  @Builder
  bannerContent(data:IData[]|Record<string,Object>[], index:number) {
    Stack({ alignContent: Alignment.Center }){
      Image(this.IMAGE_RESOURCES[index % this.IMAGE_RESOURCES.length])
        .objectFit(ImageFit.Fill)
        .width('100%')
        .height('100%')

      Flex({direction:FlexDirection.Row,justifyContent:FlexAlign.Start, alignItems:ItemAlign.Center}){
        Text(`这是第${index}个页面,用户数据为:${(data[index] as Record<string,Object>)['str']}`).fontColor(Color.White)
      }
      .position({x:0,y:200})
        .height(40).width('100%')
        .backgroundColor('#44000000')
    }
    .width('100%')
      .height(240)
  }

  build() {
    Scroll(){
      Column() {

        Text('缩放渐变动效展示+指示器与banner分离').margin({top:20,bottom:20})

        Stack() {

          Banner({
            bannerOptions: this.bannerOptions,
            currentPosition: $currentPos1,
            data: this.data,
            bannerContent: (item, index) => {
              this.bannerContent(item, index)
            }
          }).width('100%')
            .height(240)

          Flex({direction:FlexDirection.RowReverse,justifyContent:FlexAlign.Start, alignItems:ItemAlign.Center}){
          }
          .width('100%')
            .height(40)
            .position({x:0,y:200})

        }.width('100%')
          .height(240)

        Flex({direction:FlexDirection.RowReverse,justifyContent:FlexAlign.Start, alignItems:ItemAlign.Center}){
          Text(`${(this.itemIndex+1)}/${this.data.length}`).fontColor(Color.White).margin({left:20,right:40})

          CircleIndicator({ indicatorConfig: this.indicatorConfig })
        }
        .width('100%')
          .height(40)
          .backgroundColor(Color.Gray)

      }.width('100%')
    } .width('100%')
      .height('100%')

  }

接口说明

Banner 轮播自定义组件

方法名入参接口描述
Banner({bannerOptions: $bannerOptions,data: $data,bannerContent: (item, index) => {this.bannerContent(item, index)}}自定义轮播组件Banner构造器

CircleIndicator 指示器自定义组件

方法名入参接口描述
CircleIndicator({ indicatorConfig: $indicatorConfig })indicatorConfig:IndicatorConfig圆角指示器构造器

PixelMapIndicator 指示器自定义组件

方法名入参接口描述
PixelMapIndicator({ indicatorConfig: $indicatorConfig })indicatorConfig:IndicatorConfig图像指示器构造器

RectFIndicator 指示器自定义组件

方法名入参接口描述
RectFIndicator({ indicatorConfig: $indicatorConfig })indicatorConfig:IndicatorConfig矩形指示器构造器

RoundLinesIndicator 指示器自定义组件

方法名入参接口描述
RoundLinesIndicator({ indicatorConfig: $indicatorConfig })indicatorConfig:IndicatorConfig圆角线条指示器构造器

IndicatorConfig自定义组件配置

使用方法入参接口描述
getNormalPixelMap()获取普通图像指示器未选中图像
setNormalPixelMap(normal)normal:PixelMap设置普通图像指示器未选中图像
getSelectPixelMap()获取普通图像指示器选中图像
setSelectPixelMap(select)select:PixelMap设置普通图像指示器选中图像
getHeight()获取指示器的高度
setHeight(height)height: number设置指示器的高度
getRadius()获取指示器的圆角
setRadius(radius)radius: number设置指示器的圆角
getSelectedWidth()获取指示器选中宽度
setSelectedWidth(selectedWidth)selectedWidth: number设置指示器选中宽度
getNormalWidth()获取指示器未选中宽度
setNormalWidth(normalWidth)normalWidth: number设置指示器未选中宽度
getCurrentPosition()获取指示器当前位置
setCurrentPosition(currentPosition: number)currentPosition: number设置指示器当前位置
getIndicatorSpace()获取指示器间距
setIndicatorSpace(indicatorSpace: number)indicatorSpace: number设置指示器间距
getSelectedColor()获取指示器选中颜色
setSelectedColor(selectedColor: string)selectedColor: string设置指示器选中颜色
getNormalColor()获取指示器未选中颜色
setNormalColor(normalColor: string)normalColor: string设置指示器未选中颜色
getIndicatorSize()获取指示器总数
setIndicatorSize(indicatorSize: number)indicatorSize: number设置指示器总数

AnimatedEnum动画类型支持

动画类型展示动画类型描述
AnimatedEnum.NonePage无动画效果
AnimatedEnum.AlphaPagealpha渐变
AnimatedEnum.DepthPage叠层
AnimatedEnum.MZScaleIn魅族效果 通常配合画廊
AnimatedEnum.RotateDownPage圆形旋转翻页 中心点在下方
AnimatedEnum.RotateUpPage圆形旋转翻页 中心点在上方
AnimatedEnum.RotateY3D旋转翻页 旋转轴Y
AnimatedEnum.ScaleIn缩放进入
AnimatedEnum.ZoomOutPage缩放alpha进入

BannerOptions Banner配置参数

export class BannerOptions{
  swiperController:SwiperController = new SwiperController();
  autoPlay?:boolean = false // 自定播放
  interval?:number = 3000 // 当前item停滞时间
  indicator?:SwiperIndicator = { bool: false} // 系统的指示器配置 不启用设置false
  loop?:boolean = true // 是否开启循环
  duration?:number = 400 // 子组件切换动画时长
  vertical?:boolean = false // 是否纵向滑动
  curve?:Curve = Curve.Linear // 动画曲率
  disableSwipe?:boolean = false; // 禁止触摸

  bannerMargin?:BannerMargin = {left:0, right:0};// 水平是左右的margin,垂直为上下的margin
  animatedEnum?:AnimatedEnum = AnimatedEnum.NonePage// 动画效果
  animatedConfig?:AnimatedConfig = {}

  onChange?: (index:number)=>void = undefined; // swiper当前index回调
  onGestureSwipe?:(index: number, extraInfo:SwiperAnimationEvent)=>void = undefined // swiper手势回调
  onAnimationStart?:(index: number, targetIndex: number, extraInfo:SwiperAnimationEvent)=>void = undefined // swiper动画开始回调
  onAnimationEnd?:(index: number, extraInfo:SwiperAnimationEvent)=>void = undefined // swiper动画结束回调

}

约束与限制

在下述版本验证通过:

DevEco Studio NEXT Developer Beta3: (5.0.3.530), SDK: API12 (5.0.0.35(SP3))

目录结构

|---- banner
|     |---- entry  # 示例代码文件夹
			|----pages # 页面测试代码
				|----index.ets #测试文件列表
				|----BannerConfigPage.ets 		#Banner配置展示页面
				|----IndicatorConfigPage.ets 	#Indicator指示器配置展示页面
				|----BannerSamplePage.ets		#一些常用场景指导
|     |---- screenshots #截图
|     |---- banner  # banner库文件夹
|           |---- src  # banner库核心代码
				|----component
					 |----Banner.ets 			#自定义组件Banner
					 |----BannerOptions.ets  	#自定义组件Banner的配置参数
					 |----TransformerBanner.ets #自定义Banner内容变换核心
				|---- config 					#指示器默认配置
				|---- indicator   				#指示器默认配置
					 |----CircleIndicator.ets 				#自定义指示器组件CircleIndicator
					 |----PixelMapIndicator.ets 			#自定义指示器组件PixelMapIndicator
					 |----RectFIndicator.ets 				#自定义指示器组件RectFIndicator
					 |----RoundLinesIndicator.ets 			#自定义指示器组件RoundLinesIndicator
				|---- transformer   			#动画枚举以及自定义数据传递
|           |---- index.ets  # banner 对外暴露接口
|     |---- README.MD  # 安装使用方法
|     |---- README_zh.MD  # 安装使用方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值