目录
1、Swiper轮播组件
1.1 Swiper基本用法
1.2 Swiper的常见属性
1.3 Swiper的样式自定义
1.3.1 基本语法
1.3.2 案例小米有品
2、样式&结构重用
2.1 @Extend:扩展组件(样式、事件)
2.2 @Styles:抽取通用属性、事件
2.3 @Builder:自定义构建函数(结构、样式、事件)
3、滚动容器Scroll
3.1 Scroll 的核心用法
3.2 Scroll 的常见属性
3.3 Scroll 的控制器
3.4 Scroll 的事件
3.5 案例:京东案例实战
4、容器组件Tabs
4.1 Tabs 基本用法
4.2 Tabs 常用属性
4.3 滚动导航栏
4.4 自定义TabBar
4.4.1 基础结构
4.4.2 高亮切换
4.5 案例:小米有品底部Tabs
前言:组件化开发-样式结构重用&常见组件
1、Swiper轮播组件
1.1 Swiper基本用法
import window from '@ohos.window';
@Entry
@Componentstruct Index {onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column(){Swiper(){Text('1').backgroundColor(Color.Yellow)Text('2').backgroundColor(Color.Orange)Text('3').backgroundColor(Color.Brown)}.width('100%').height(100).margin({bottom: 5})Swiper(){Image($r('app.media.ic_swiper_xmyp01'))Image($r('app.media.ic_swiper_xmyp02'))Image($r('app.media.ic_swiper_xmyp03'))Image($r('app.media.ic_swiper_xmyp04'))}.width('100%').height(150)}}
}
1.2 Swiper的常见属性
import window from '@ohos.window';
@Entry
@Componentstruct Index {onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column(){ Swiper(){Image($r('app.media.ic_swiper_xmyp01'))Image($r('app.media.ic_swiper_xmyp02'))Image($r('app.media.ic_swiper_xmyp03'))Image($r('app.media.ic_swiper_xmyp04'))}.loop(false) //是否开启循环 默认true,flase无法左滑到末页.autoPlay(true) // 自动播放 默认是false自动播放.invert(4000) // 播放间隔 默认3000.vertical(false) //纵向滑动轮播默认flase,true就是纵向.width('100%').height(150)}}
}
1.3 Swiper的样式自定义
1.3.1 基本语法
import window from '@ohos.window';
import { InterstitialDialogAction } from '@ohos.atomicservice.InterstitialDialogAction';@Entry
@Componentstruct Index {onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column(){Swiper(){Text('1').backgroundColor(Color.Yellow)Text('2').backgroundColor(Color.Orange)Text('3').backgroundColor(Color.Brown)}.width('100%').height(200).margin({bottom: 5})// .indicator(true) //定制小圆点。默认false.indicator(Indicator.dot().itemWidth(20).itemHeight(20).color(Color.Black).selectedItemWidth(25).selectedItemHeight(25).selectedColor(Color.White))Swiper(){Image($r('app.media.ic_swiper_xmyp01'))Image($r('app.media.ic_swiper_xmyp02'))Image($r('app.media.ic_swiper_xmyp03'))Image($r('app.media.ic_swiper_xmyp04'))}.loop(false) //是否开启循环 默认true,flase无法左滑到末页.autoPlay(true) // 自动播放 默认是false自动播放.invert(4000) // 播放间隔 默认3000.vertical(false) //纵向滑动轮播默认flase,true就是纵向.width('100%').height(150)}}
}
1.3.2 案例小米有品
import window from '@ohos.window';
import { InterstitialDialogAction } from '@ohos.atomicservice.InterstitialDialogAction';@Entry
@Componentstruct Index {onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column(){Swiper(){Image($r('app.media.ic_swiper_xmyp01'))Image($r('app.media.ic_swiper_xmyp02'))Image($r('app.media.ic_swiper_xmyp03'))Image($r('app.media.ic_swiper_xmyp04'))}.width('100%').aspectRatio(2.4) // 宽高比.autoPlay(true) // 自动播放 默认是false自动播放.invert(4000) // 播放间隔 默认3000.indicator(Indicator.dot().itemWidth(10).selectedItemWidth(30).selectedColor(Color.Black))}}
}
2、样式&结构重用
2.1 @Extend:扩展组件(样式、事件)
import window from '@ohos.window';@Extend(Text)
function textFn(){.fontSize(20).fontWeight(FontWeight.Bold)
}@Extend(Text)
function bannerExtend(bgColor: ResourceColor, msg: string){.textAlign(TextAlign.Center).backgroundColor(bgColor).fontColor(Color.White).fontSize(30).onClick(() => {AlertDialog.show({message: msg})})
}@Entry
@Componentstruct Index {@State message: string = '@Extend-扩展组件(样式,事件)';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column() {Text(this.message).textFn()Swiper() {Text('1').bannerExtend(Color.Orange, '轮播图1号')Text('2').bannerExtend(Color.Brown, '轮播图2号')Text('3').bannerExtend(Color.Green, '轮播图3号')}.width('100%').height(160)}.width('100%').height('100%')}
}
2.2 @Styles:抽取通用属性、事件
下图有Text、Button、Column是无法使用Extend实现,那么需要学习Styles,Styles可以全局定义、可以在组件里面定义,但是不支持传参
import window from '@ohos.window';// 1 全局定义
@Styles function commonStyles (){.width(100).height(100)
}@Entry
@Componentstruct Index {@State message: string = '@styles';@State bgColor: ResourceColor = Color.Gray// 2、 组件内定义@Styles SetBg (){.backgroundColor(this.bgColor).onClick(() => {this.bgColor = Color.Orange})}onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column({ space: 10 }) {Text(this.message).fontColor(Color.White).commonStyles().SetBg()Column() {}.commonStyles().SetBg()Button('按钮').commonStyles().SetBg()Button('重置').commonStyles().onClick( () => {this.bgColor = Color.Gray})}.width('100%').height('100%')}
}
2.3 @Builder:自定义构建函数(结构、样式、事件)
注意全局与局部区别(this.xxx)
import window from '@ohos.window';// 1 全局定义
@Builder
function navItem (icon: ResourceStr, txt: string){Column({ space: 10 }) {Image(icon).width('80%')Text(txt)}.width('25%').onClick(() => {AlertDialog.show({message: `点了 ${txt}`})})
}@Entry
@Componentstruct Index {@State message: string = '@Builder';// 2 局部定义@BuildernavItem (icon: ResourceStr, txt: string){Column({ space: 10 }) {Image(icon).width('80%')Text(txt)}.width('25%').onClick(() => {AlertDialog.show({message: `点了 ${txt}`+ this.message})})
}onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column({ space: 20 }) {Text(this.message).fontSize(30)Row() {Row() {navItem($r('app.media.ic_reuse_01'), '阿里拍卖')navItem($r('app.media.ic_reuse_02'), '菜鸟')this.navItem($r('app.media.ic_reuse_03'), '芭芭农场')this.navItem($r('app.media.ic_reuse_04'), '医药')}}}.width('100%').height('100%')}}
3、滚动容器Scroll
3.1 Scroll 的核心用法
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column() {// 如果需要滚动,外层Scroll(){Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical) // .scrollable(ScrollDirection.Horizontal) //横向}}}
3.2 Scroll 的常见属性
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Column() {// 如果希望内容溢出, 能够滚动Scroll() {Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical) // 设置滚动方向.scrollBar(BarState.Auto) // On一直显示 Off一直隐藏 Auto滑动显示.scrollBarColor(Color.Blue) // 滚动条颜色.scrollBarWidth(5) // 滚动条宽度.edgeEffect(EdgeEffect.Spring) // 滑动效果}}
}
3.3 Scroll 的控制器
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}// 1. 创建 Scroller 对象 (实例化)myScroll: Scroller = new Scroller()build() {Column() {// 如果希望内容溢出, 能够滚动// 2. 绑定给 Scroll 组件Scroll(this.myScroll) {Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical) // 设置滚动方向.scrollBar(BarState.Auto) // On一直显示 Off一直隐藏 Auto滑动显示.scrollBarColor(Color.Blue) // 滚动条颜色.scrollBarWidth(5) // 滚动条宽度.edgeEffect(EdgeEffect.Spring) // 滑动效果Button('控制滚动条位置').margin(20).onClick(() => {this.myScroll.scrollEdge(Edge.End)})Button('获取已经滚动的距离').onClick(() => {const x = this.myScroll.currentOffset().xOffsetconst y = this.myScroll.currentOffset().yOffsetAlertDialog.show({message: `x: ${x} y: ${y}`})})}}
}
3.4 Scroll 的事件
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}// 1. 创建 Scroller 对象 (实例化)myScroll: Scroller = new Scroller()build() {Column() {// 如果希望内容溢出, 能够滚动// 2. 绑定给 Scroll 组件Scroll(this.myScroll) {Column({ space: 10 }) {ForEach(Array.from({ length: 10 }), (item: string, index) => {Text('测试文本' + (index + 1)).width('100%').height(100).textAlign(TextAlign.Center).backgroundColor(Color.Orange).fontSize(20).fontColor(Color.White).borderRadius(10)})}.padding(10).width('100%')}.width('100%').height(400).scrollable(ScrollDirection.Vertical) // 设置滚动方向.scrollBar(BarState.Auto) // On一直显示 Off一直隐藏 Auto滑动显示.scrollBarColor(Color.Blue) // 滚动条颜色.scrollBarWidth(5) // 滚动条宽度.edgeEffect(EdgeEffect.Spring) // 滑动效果.onScroll((x, y) => {console.log('已经滑动的距离:', this.myScroll.currentOffset().yOffset)})Button('控制滚动条位置').margin(20).onClick(() => {this.myScroll.scrollEdge(Edge.End)})Button('获取已经滚动的距离').onClick(() => {const y = this.myScroll.currentOffset().yOffsetAlertDialog.show({message: `y: ${y}`})})}}
}
3.5 案例:京东案例实战
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}// 1、 创建scroll实例对象myScroll: Scroller = new Scroller()@State yOffset: number = 0build() {Column() {Stack({ alignContent: Alignment.BottomEnd }) {// 顶部滚动区域// 2 和Scroll容器绑定Scroll(this.myScroll) {Column() {Image($r('app.media.ic_jd_scroll_01'))Image($r('app.media.ic_jd_scroll_02'))Image($r('app.media.ic_jd_scroll_03'))}}.scrollBar(BarState.Off).width('100%').backgroundColor(Color.Orange).onScroll( () => {this.yOffset = this.myScroll.currentOffset().yOffset})// 有时显示 有时隐藏-》条件渲染if( this.yOffset > 400){ Image($r('app.media.ic_jd_rocket')).width(40).backgroundColor(Color.White).borderRadius(20).padding(5)// .margin({right:20,bottom:20}).offset({ x: -20, y: -20 })// 3 添加事件.onClick( () => {this.myScroll.scrollEdge(Edge.Top)})}}.layoutWeight(1)// 底部 tabbar 图片(后面会学)Image($r('app.media.ic_jd_tab')).width('100%')}}
}
4、容器组件Tabs
4.1 Tabs 基本用法
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Tabs(){TabContent(){Text('首页内容') // 只能有一个子组件}.tabBar('首页')TabContent(){Text('推荐内容')}.tabBar('推荐')TabContent(){Text('发现内容')}.tabBar('发现')TabContent(){Text('我的')}.tabBar('我的')}}
}
4.2 Tabs 常用属性
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('首页内容') // 有且只能一个子组件}.tabBar('首页') // 配置导航TabContent() {Text('推荐内容') // 有且只能一个子组件}.tabBar('推荐')TabContent() {Text('发现内容') // 有且只能一个子组件}.tabBar('发现')TabContent() {Text('我的内容') // 有且只能一个子组件}.tabBar('我的')}.vertical(false) // 调整导航水平或垂直.scrollable(false) // 是否开启手势滑动.animationDuration(0) // 点击滑动的动画时间}
}
4.3 滚动导航栏
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}titles: string[] = ['首页','关注','热门','军事','体育','八卦','数码','财经','美食','旅行']build() {// 生成10个面板 → 10个小导航Tabs() {ForEach(this.titles, (item: string, index) => {TabContent() {Text(`${item}内容`)}.tabBar(item)})}// barMode属性, 可以实现滚动导航栏.barMode(BarMode.Scrollable)}
}
4.4 自定义TabBar
4.4.1 基础结构
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}@BuildermyBuilder (title: string, img: ResourceStr) {Column() {Image(img).width(30)Text(title)}}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('购物车内容')}.tabBar(this.myBuilder('购物车', $r('app.media.ic_tabbar_icon_2')))TabContent() {Text('我的内容')}.tabBar(this.myBuilder('我的', $r('app.media.ic_tabbar_icon_3')))}}
}
4.4.2 高亮切换
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}// 准备状态, 存储激活的索引@State selectedIndex: number = 0@BuildermyBuilder (itemIndex: number, title: string, img: ResourceStr, selImg: ResourceStr) {// 如果激活的是自己, 图片/文本 都需要调整样式 → 需要区分不同的 tabBarColumn() {Image(itemIndex == this.selectedIndex ? selImg : img).width(30)Text(title).fontColor(itemIndex == this.selectedIndex ? Color.Red : Color.Black)}}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('购物车内容')}.tabBar(this.myBuilder(0, '购物车', $r('app.media.ic_tabbar_icon_2'), $r('app.media.ic_tabbar_icon_2_selected')))TabContent() {Text('我的内容')}.tabBar(this.myBuilder(1, '我的', $r('app.media.ic_tabbar_icon_3'), $r('app.media.ic_tabbar_icon_3_selected')))}.onChange((index: number) => {// console.log('激活的索引', index)this.selectedIndex = index}).animationDuration(0).scrollable(false)}
}
4.5 案例:小米有品底部Tabs
import window from '@ohos.window';@Entry
@Component
struct Index {@State message: string = '@春天的菠菜';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setFullScreen(true)});}// 准备状态, 存储激活的索引@State selectedIndex: number = 0@BuildermyBuilder (itemIndex: number, title: string, img: ResourceStr, selImg: ResourceStr) {// 如果激活的是自己, 图片/文本 都需要调整样式 → 需要区分不同的 tabBarColumn() {Image(itemIndex == this.selectedIndex ? selImg : img).width(30)Text(title).fontColor(itemIndex == this.selectedIndex ? Color.Red : Color.Black)}}@BuildercenterBuilder () {Image($r('app.media.ic_reuse_02')).width(40).margin({ bottom: 10 })}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Text('首页内容')}.tabBar(this.myBuilder(0, '首页', $r('app.media.ic_tabbar_icon_0'), $r('app.media.ic_tabbar_icon_0_selected')))TabContent() {Text('分类内容')}.tabBar(this.myBuilder(1, '分类', $r('app.media.ic_tabbar_icon_1'), $r('app.media.ic_tabbar_icon_1_selected')))// 特殊形状的TabTabContent() {Text('活动内容')}.tabBar(this.centerBuilder())TabContent() {Text('购物车内容')}.tabBar(this.myBuilder(3, '购物车', $r('app.media.ic_tabbar_icon_2'), $r('app.media.ic_tabbar_icon_2_selected')))TabContent() {Text('我的内容')}.tabBar(this.myBuilder(4, '我的', $r('app.media.ic_tabbar_icon_3'), $r('app.media.ic_tabbar_icon_3_selected')))}.onChange((index: number) => {// console.log('激活的索引', index)this.selectedIndex = index}).animationDuration(0).scrollable(false)}
}