序言:
本文详细讲解了关于我们在页面上经常看到的可滚动页面和导航栏在鸿蒙开发中如何用Scroll和Tabs组件实现,介绍了Scroll和Tabs的基本用法与属性。
笔者也是跟着B站黑马的课程一步步学习,学习的过程中添加部分自己的想法整理为笔记分享出来,如有代码错误或笔误,欢迎指正。
B站黑马的课程链接:鸿蒙课程介绍_哔哩哔哩_bilibili
往期笔记:
【01】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-ArkTs基础语法与界面开发基础
【02】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-界面进阶与布局排布(附QQ登陆、得物、京东登陆综合案例+代码)
【03】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-更多布局(弹性/层叠)方式与界面开发综合(附飞狗卡片+B站卡片案例+实战开发支付宝界面+代码)
【04】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-ArkTs进阶运算符+状态管理(附综合案例美团购物车)
【05】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-条件渲染+if/switch判断与for/while循环(附计数器、京东加购案例)
【06】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-综合案例·生肖抽奖卡具体实现(类似支付宝集五福)
【07】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Swiper轮播组件与样式&结构重用
目录
一.滚动容器Scroll
1.Scroll-核心用法
2.Scroll-常见属性
3.Scroll-控制器
4.Scroll-事件
5.Scroll-京东案例
二.Tabs组件
1.Tabs-基本使用
2.Tabs-自定义TabBar-基础结构
3.Tabs-自定义TabBar-高亮切换
一.滚动容器Scroll
简介:当子组件的布局尺寸超出Scroll的尺寸时,内容可以滚动
1.Scroll-核心用法
1)用法说明:
①Scroll设置尺寸
②设置溢出的子组件(只支持一个子组件)
③滚动方向(支持横向和纵向,默认纵向)
2)代码示意:
build() {
Scroll(){
//只支持一个子组件
Column(){
//内容放在内部
//尺寸超过Scroll即可滚动
}
}
.width('100%')
.height(200)
.scrollable(ScrollDirection.xxx)//设置滚动方向
}
//.scrollable(ScrollDirection.Vertical) 纵向
//.scrollable(ScrollDirection.Horizontal)横向
2.Scroll-常见属性
1)常用参数:
名称 | 参数类型 | 描述 |
scrollBar | BarState | 设置滚动条状态 |
scrollBarColor | string|number|Color | 设置滚动条颜色 |
scrollBarWidth | string|number | 设置滚动条宽度 |
edgeEffect | value:EdgeEffect | 设置边缘滑动效果 EdgeEffect.None 无 EdgeEffect.Spring 弹簧 EdgeEffect.Fade 阴影 |
scrollable | ScrollDirection | 设置滚动方向 ScrollDirection.Vertical) 纵向 ScrollDirection.Horizontal)横向 |
2)代码示意:
build() {
Column() {
Scroll() {
Column() {
ForEach(Array.from({ length: 10 }), (item: string, index) => {
Text('测试文本')
.width('100%')
.height(100)
.backgroundColor(Color.Grey)
.margin(20)
})
}
.padding(10)
.width('100%')
}
.width('100%')
.height(400)
.scrollable(ScrollDirection.Vertical) //设置滚动方向
.scrollBar(BarState.On) //On令滚动条恒存在 Off恒隐藏 Auto滑动显示
.scrollBarColor(Color.Blue) //滚动条颜色
.scrollBarWidth(5) //滚动条宽度
.edgeEffect(EdgeEffect.Spring) //滚动条弹簧效果
}
}
3.Scroll-控制器
1)核心步骤:
①实例化Scroll的控制器
②绑定给Scroll组件
③控制器的方法控制滚动,控制其属性获取滚动距离
2)代码示意:
struct Index {
//1.创建Scroller对象(实例化)
myscroller:Scroller = new Scroller()
build() {
Column({ space: 10 }) {
Scroll(this.myscroller) {
Column() {
ForEach(Array.from({ length: 10 }), (irem: string, index) => {
Text('测试文本')
.width('100%')
.height(100)
.backgroundColor(Color.Grey)
.margin(20)
})
}
.padding(10)
.width('100%')
}
.width('100%')
.height(400)
.scrollable(ScrollDirection.Vertical) //设置滚动方向
.scrollBar(BarState.On) //On令滚动条恒存在 Off恒隐藏 Auto滑动显示
.scrollBarColor(Color.Blue) //滚动条颜色
.scrollBarWidth(5) //滚动条宽度
.edgeEffect(EdgeEffect.Spring) //滚动条弹簧效果
Button('控制滚动条位置')
.margin(20)
.onClick(()=>{
this.myscroller.scrollEdge(Edge.Top) //控制滚动条到顶部
})
Button('获取已经滚动的距离')
.onClick(()=>{
const y = this.myscroller.currentOffset().yOffset
AlertDialog.show({
message:`'y':${y}`
})
})
}
}
}
4.Scroll-事件
简介:Scroll组件提供了一些事件,让开发者可以在适当的时候添加逻辑。
Scroll(){
//内容略
}
.onScroll((x,y))=>{
//滚动时 一直触发
//可以结合 scroller的currentOffset方案,获取滚动距离
}
1)代码示意:
Scroll(this.myscroller) {
Column() {
ForEach(Array.from({ length: 10 }), (irem: string, index) => {
Text('测试文本')
.width('100%')
.height(100)
.backgroundColor(Color.Grey)
.margin(20)
})
}
.padding(10)
.width('100%')
}
.width('100%')
.height(400)
.scrollable(ScrollDirection.Vertical) //设置滚动方向
.scrollBar(BarState.On) //On令滚动条恒存在 Off恒隐藏 Auto滑动显示
.scrollBarColor(Color.Blue) //滚动条颜色
.scrollBarWidth(5) //滚动条宽度
.edgeEffect(EdgeEffect.Spring) //滚动条弹簧效果
.onScroll((x,y)=>{
console.log('已经滑动的距离:',this.myscroller.currentOffset().yOffset)
})
5.Scroll-京东案例
1)代码示意:
@Entry
@Component
struct Index {
//1.创建Scroll实例对象
myscroller:Scroller = new Scroller()
@State yOffset:number = 0 //实时保存y轴距离
build() {
Column() {
Stack({ alignContent: Alignment.BottomEnd }) {
// 顶部滚动区域
//2.和scroller容器绑定
Scroll(this.myscroller) {
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.myscroller.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 })
.onClick(()=>{
this.myscroller.scrollEdge(Edge.Top)})
}
.layoutWeight(1)
// 底部 tabbar 图片(后面会学)
Image($r('app.media.ic_jd_tab'))
.width('100%')
}
}
}
二.Tabs组件
当页面内容较多时,可以通过Tabs组件进行分类展示
Tab里面还可以有Tab
1.Tabs-基本使用
1)基本用法:
Tabs(){
TabContent(){
Text('首页内容') //有且只能有一个子组件,如果内容比较复杂,可以用Column这种
}
.tabBar('首页') //配置导航
TabContent(){
Text('推荐内容') //有且只能有一个子组件,如果内容比较复杂,可以用Column这种
}
.tabBar('推荐') //配置导航
TabContent(){
Text('发现内容') //有且只能有一个子组件,如果内容比较复杂,可以用Column这种
}
.tabBar('发现') //配置导航
TabContent(){
Text('我的') //有且只能有一个子组件,如果内容比较复杂,可以用Column这种
}
.tabBar('我的') //配置导航
}
2)常用属性
名称 | 作用 |
barPosition | 调整位置 开头 或 结尾 参数 |
vertical | 调整导航 水平 或 垂直 |
scrollable | 调整是否手势滑动 切换 |
animationDuration | 点击滑动动画时间 |
①写法位置
3)滚动导航栏
如果导航栏的内容较多,屏幕无法容纳时,可以将它设置为滚动
可以通过Tabs组件的barMode属性即可调整固定导航栏或滚动导航栏
①代码示意:
tieles:string[]=[
'首页','关注','热门','军事','体育',
'八卦','数码','财经','美食','旅行',
]
//生成十个面板+十个小导航
Tabs(){
ForEach(this.tieles,(item:string,index)=>{
TabContent(){
Text('我是内容')
}
.tabBar(`${item}内容`)
})
}
.barMode(BarMode.Scrollable)
2.Tabs-自定义TabBar-基础结构
TabBar在底部,一般会显示图形和文字,甚至有一些特殊logo
1)代码示意:
@Entry
@Component
struct Index {
@Builder
myBuilder(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')))
}
}
}
3.Tabs-自定义TabBar-高亮切换
1)核心思路:
①监听切换事件→得到索引值,记录高亮的索引
②给每个tabber起一个标记,0,1,2
③在taber内部比较标记==记录的索引?高亮:不高亮
名称 | 功能描述 |
onChange(event:(index:number)=>void) | Tab页签切换后触发的事件。 -index:当前显示的index索引,索引从0开始计算。 滑动切换、点击切换 均会触发 |
onTabbarClick(event:(index:number)=>void)10+ | Tab页签点击后触发的事件。 -index:被点击的index索引,索引从0开始计算。 |
2)代码示意:
@Entry
@Component
struct Index {
//准备状态,存储激活的索引
@State selectIndex:number=0
@Builder
myBuilder(itemIndex:number,title:string,img:ResourceStr,selImg:ResourceStr){
//如果激活的是自己,图文/文本,都需要调整样式->需要区分不同的 tabar
Column(){
Image(
itemIndex==this.selectIndex?selImg:img
)
.width(30)
Text(title)
.fontColor(itemIndex==this.selectIndex?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.selectIndex = index
})
}
}
感谢观看