当前位置: 首页 > news >正文

HarmonyOS ArkUi Tabs+TabContent+List实现tab吸顶功能

Demo效果

@Entry
@Component
struct StickyNestedScroll {@State message: string = 'Hello World'@State arr: number[] = []scroller = new Scroller()@StyleslistCard() {.backgroundColor(Color.White).height(72).width("100%").borderRadius(12)}build() {Scroll(this.scroller) {Column() {Stack({ alignContent: Alignment.Top }) {Column() {}.height("200vp").width('100%').backgroundImage($r('app.media.icon_home_top'))// Text('吸顶').width('100%').height(40).backgroundColor(Color.Black).zIndex(999)}Tabs({ barPosition: BarPosition.Start }) {TabContent() {List({ space: 10 }) {ForEach(this.arr, (item: number) => {ListItem() {Text("item" + item).fontSize(16)}.listCard()}, (item: string) => item)}.width("100%").edgeEffect(EdgeEffect.Spring).nestedScroll({scrollForward: NestedScrollMode.PARENT_FIRST,scrollBackward: NestedScrollMode.SELF_FIRST})}.tabBar("Tab1")TabContent() {}.tabBar("Tab2")}.vertical(false).backgroundColor(Color.Brown).height("100%")}.width("100%")}.edgeEffect(EdgeEffect.Spring).friction(0.6).backgroundColor('#DCDCDC').scrollBar(BarState.Off).width('100%').height('100%')}aboutToAppear() {for (let i = 0; i < 30; i++) {this.arr.push(i)}}@BuildertestHead() {Text('吸顶').width('100%').height(40).backgroundColor(Color.Black).zIndex(999)}
}

项目实战效果图

  • Tab:(企业统计)
  @BuilderTabWidget() {Row() {Text('企业统计').fontColor($r('app.color.color303242')).fontSize(16).margin({ left: 12 })}.height('100%').width('calc(100% - 30vp)').borderRadius({ topLeft: 8, topRight: 8 }).backgroundColor(Color.White).margin({ left: 15, right: 15 }).onClick(() => {this.scroller.scrollTo({ xOffset: 0, yOffset: 2000 })})}
  • 完整项目代码

仔细看代码里的注释


@Entry
@Component
export struct HomePage {@State curIndex: number = 0scroller: Scroller = new Scroller()@State currentOffset: number = 0;@StorageLink('systemBarHeight') systemBarHeight: number = 0@State topOpacity: number = 1;@State searchHint: string = '请输入企业名称';@State banner?: BannerBean = new BannerBean()@State protMarketBean?: ProspectMarketBean[] = new Array<ProspectMarketBean>()aboutToAppear(): void {}build() {Stack({ alignContent: Alignment.Top }) {Scroll(this.scroller) {Column() {Column() {// tab 企业统计上面的组件   这里省略 l里面没内容的话 可以设置固定高度测试// ....}.width('100%')Tabs({ barPosition: BarPosition.Start }) {TabContent() {// 注意注意: 这里是tab 企业统计下面的界面  这里要用listList({ space: 10 }) {ListItem() {Column() {HomeWebWidget()if (this.protMarketBean && this.protMarketBean.length > 0) {HomeEnterpriseLib({ protMarketBean: this.protMarketBean }).margin({ top: 10 })}}.width('100%')}}.width("100%").height('100%')// edgeEffect  nestedScroll一定要设置.edgeEffect(EdgeEffect.Spring).nestedScroll({scrollForward: NestedScrollMode.PARENT_FIRST,scrollBackward: NestedScrollMode.SELF_FIRST})}.tabBar(this.TabWidget())}.barWidth('100%').barHeight(40).vertical(false).margin({ top: 10 })//60=搜索组件的高度 this.systemBarHeight= 状态栏的高度  这样吸顶才是刚好处于搜索组件下方  可自行调整.height(`calc(100% - ${60 + px2vp(this.systemBarHeight)}vp)`)}.width("100%").backgroundImage($r('app.media.icon_home_top')).backgroundImageSize({ width: '100%', height: '50%' })}.onScroll(() => {// 滚动监听  根据偏移量 顶部搜索栏的界面效果this.currentOffset = this.scroller.currentOffset().yOffset;// 根据偏移控制透明度this.topOpacity = (140 - this.currentOffset) / 140;}).edgeEffect(EdgeEffect.Spring).friction(0.6).backgroundColor('#F3F3F3').scrollBar(BarState.Off).width('100%').height('100%')// 滚动偏移量大于0时  显示顶部搜索if (this.currentOffset > 0) {this.SearchHeaderWidget()}}}@BuilderTabWidget() {Row() {Text('企业统计').fontColor($r('app.color.color303242')).fontSize(16).margin({ left: 12 })}.height('100%').width('calc(100% - 30vp)') .borderRadius({ topLeft: 8, topRight: 8 }).backgroundColor(Color.White).margin({ left: 15, right: 15 }).onClick(() => {this.scroller.scrollTo({ xOffset: 0, yOffset: 2000 })})}@BuilderSearchHeaderWidget() {Column() {Row() {Image($r('app.media.icon_search')).width(18).height(18).margin({ left: 15 })Text(this.searchHint).fontColor('#C6C9CF').fontSize(13).margin({ left: 8 })}.height(40).width('100%').backgroundColor(Color.White).borderRadius(50).onClick(() => {router.pushUrl({ url: RouterPath.SEARCH, params: { tabIndex: 1 } })}).margin({ top: px2vp(this.systemBarHeight) })}.backgroundColor('#0256FF').padding({ left: 15, right: 15, bottom: 10, top: 10 }).opacity(1 - this.topOpacity) // 顶部搜索组件的透明度}
}

相关文章:

  • 【Git-驯化】一文学会git配置用户信息,git config用法细节
  • Selenium:原理与使用指南
  • 麒麟V10安装MinIO
  • CICD流水线-父子项目打包发布至私仓库
  • 【数据分享】国家级旅游休闲街区数据(Excel/Shp格式/免费获取)
  • 大模型思维链(Chain-of-Thought)技术原理
  • 网络爬虫(一)深度优先爬虫与广度优先爬虫
  • 查看视频时间基 time_base
  • Java操作Excel最佳实践
  • 数据结构——求两个数的最大公因子
  • 面试篇-系统设计题总结
  • 开发AI黑客机器人并上传全云端
  • ReactNative如何实现沉浸式状态栏及渐变色Header【兼容Android和iOS】
  • TreeSize Free - 硬盘空间管理工具
  • Beyond Low-frequency Information in Graph Convolutional Networks
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • echarts花样作死的坑
  • EOS是什么
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • Rancher-k8s加速安装文档
  • Sublime text 3 3103 注册码
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • TypeScript迭代器
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 将回调地狱按在地上摩擦的Promise
  • 最近的计划
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • Java性能优化之JVM GC(垃圾回收机制)
  • 阿里云服务器如何修改远程端口?
  • 回归生活:清理微信公众号
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • #pragma once
  • (1)虚拟机的安装与使用,linux系统安装
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (30)数组元素和与数字和的绝对差
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (python)数据结构---字典
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (十一)手动添加用户和文件的特殊权限
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (转) RFS+AutoItLibrary测试web对话框
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .Net Core和.Net Standard直观理解
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • @Autowired和@Resource装配
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • @RunWith注解作用
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • [ NOI 2001 ] 食物链
  • [.NET]桃源网络硬盘 v7.4