10 Star 15 Fork 14

OpenHarmony-SIG / ohos_banner

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 19.52 KB
AI 代码解读
一键复制 编辑 原始数据 按行查看 历史
sunao 提交于 2024-05-14 10:39 . 更新README中的示例代码

banner

简介

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

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

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

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

下载安装

ohpm install @ohos/banner

OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包

使用说明

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
@Component
struct BannerSamplePage {
  private swiperController: SwiperController = new SwiperController()
  private touTiaoSwiperController: SwiperController = new SwiperController()
  @State data: IData[] = []

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

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


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

  @State 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'
  ]

  @State currentPos1:number = 0

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

  @State 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() {

  }

  @State 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)}}) bannerOptions: BannerOptions,data: IData[],bannerContent: (item, index) => void 自定义轮播组件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.AlphaPage alpha渐变
AnimatedEnum.DepthPage 叠层
AnimatedEnum.MZScaleIn 魅族效果 通常配合画廊
AnimatedEnum.RotateDownPage 圆形旋转翻页 中心点在下方
AnimatedEnum.RotateUpPage 圆形旋转翻页 中心点在上方
AnimatedEnum.RotateY 3D旋转翻页 旋转轴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: 5.0 Canary3 (5.0.3.221), SDK: API11 (4.1.7.5)

目录结构

|---- 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  # 安装使用方法

贡献代码

使用过程中发现任何问题都可以提 issue 给我们,当然,我们也非常欢迎你给我们发 PR

开源协议

本项目基于 Apache License 2.0 ,请自由的享受和参与开源。

1
https://gitee.com/openharmony-sig/ohos_banner.git
git@gitee.com:openharmony-sig/ohos_banner.git
openharmony-sig
ohos_banner
ohos_banner
master

搜索帮助