代码拉取完成,页面将自动刷新
本项目是适配OpenHarmony环境的一款banner库,常用于广告图片轮播场景,基于Swiper进行封装,能力如下:
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({bannerOptions: $bannerOptions,data: $data,bannerContent: (item, index) => {this.bannerContent(item, index)}}) | bannerOptions: BannerOptions,data: IData[],bannerContent: (item, index) => void | 自定义轮播组件Banner构造器 |
方法名 | 入参 | 接口描述 |
---|---|---|
CircleIndicator({ indicatorConfig: $indicatorConfig }) | indicatorConfig:IndicatorConfig | 圆角指示器构造器 |
方法名 | 入参 | 接口描述 |
---|---|---|
PixelMapIndicator({ indicatorConfig: $indicatorConfig }) | indicatorConfig:IndicatorConfig | 图像指示器构造器 |
方法名 | 入参 | 接口描述 |
---|---|---|
RectFIndicator({ indicatorConfig: $indicatorConfig }) | indicatorConfig:IndicatorConfig | 矩形指示器构造器 |
方法名 | 入参 | 接口描述 |
---|---|---|
RoundLinesIndicator({ 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.NonePage | 无动画效果 |
AnimatedEnum.AlphaPage | alpha渐变 |
AnimatedEnum.DepthPage | 叠层 |
AnimatedEnum.MZScaleIn | 魅族效果 通常配合画廊 |
AnimatedEnum.RotateDownPage | 圆形旋转翻页 中心点在下方 |
AnimatedEnum.RotateUpPage | 圆形旋转翻页 中心点在上方 |
AnimatedEnum.RotateY | 3D旋转翻页 旋转轴Y |
AnimatedEnum.ScaleIn | 缩放进入 |
AnimatedEnum.ZoomOutPage | 缩放alpha进入 |
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 ,请自由的享受和参与开源。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。