简介
本项目是适配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 # 安装使用方法
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙(HarmonyOS NEXT)最新学习路线
-
HarmonOS基础技能
- HarmonOS就业必备技能
- HarmonOS多媒体技术
- 鸿蒙NaPi组件进阶
- HarmonOS高级技能
- 初识HarmonOS内核
- 实战就业级设备开发
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开发入门教学视频》
《鸿蒙生态应用开发V2.0白皮书》
《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
《鸿蒙开发基础》
- ArkTS语言
- 安装DevEco Studio
- 运用你的第一个ArkTS应用
- ArkUI声明式UI开发
- .……
《鸿蒙开发进阶》
- Stage模型入门
- 网络管理
- 数据管理
- 电话服务
- 分布式应用开发
- 通知与窗口管理
- 多媒体技术
- 安全技能
- 任务管理
- WebGL
- 国际化开发
- 应用测试
- DFX面向未来设计
- 鸿蒙系统移植和裁剪定制
- ……
《鸿蒙进阶实战》
- ArkTS实践
- UIAbility应用
- 网络案例
- ……
获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。