# ScrollableTabRow **Repository Path**: jackiehou/scrollable-tab-row ## Basic Information - **Project Name**: ScrollableTabRow - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-01-16 - **Last Updated**: 2026-01-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ScrollableTabRow ### 介绍 ScrollableTabRow是HarmonyOS的一个轻量级的页签组件,可与HarmonyOS的Swiper配合使用实现联动滑动的动画效果,也可不搭配Swiper使用,可自定义页签,自定义指示器indicator ### 效果图 ![](https://pic1.imgdb.cn/item/696b202661bfebba125fc558.gif) ### 安装 ``` ohpm install @jackiehou/scrollable-tab-row ``` ### 使用 ```ts import {ScrollableTabRow, ScrollableTabRowState } from '@jackiehou/scrollable-tab-row'; ``` #### 基础示例 搭配Swiper使用 推荐使用状态管理V2 ```ts @Local array: string[] = Array.from({ length: 16 }, (_, index) => ('TAB-' + index)) state: ScrollableTabRowState = new ScrollableTabRowState(this.currIndex) swiperController: SwiperController = new SwiperController() build() { ScrollableTabRow({ array:this.array, state:this.state, onTabClick: (index: number) => { this.swiperController.changeIndex(index, true) //注意:调用了swiperController.changeIndex且第二个参数anim为true才返回true, //并且在Swiper的customContentTransition中调用了ScrollableTabRowState.setFraction方法. //其他情况统统返回false return true } }) Swiper(this.swiperController) { ForEach(this.array, (item: Object, index: number) => { Text(String(item)) .textAlign(TextAlign.Center) .fontSize(30) .fontWeight(FontWeight.Bold) }) } .loop(false) .autoPlay(false) .indicator(false) .width('100%') .layoutWeight(1) .customContentTransition({ timeout: 1000, transition: (proxy: SwiperContentTransitionProxy) => { //搭配Swiper实现联动滑动的动画效果,需要调用此方法 this.state.setFraction(proxy) } }) } ``` #### 状态管理V1 也可以不搭配Swiper使用 ```ts tabArray: string[] = Array.from({ length: 4 }, (_, index) => ('TAB-' + index)) colorArray: Color[] = [Color.Blue, Color.Brown, Color.Orange, Color.Pink] state: ScrollableTabRowState = new ScrollableTabRowState(0) @State contentIndexArray: number[] = [this.state.currentIndex] build() { Column({ space: 10 }) { ScrollableTabRow({ array: this.tabArray, state: this.state, barMode:BarMode.Fixed, onTabClick: (_, index: number) => { if(!this.contentIndexArray.includes(index)){ this.contentIndexArray.push(index) } //不用Swiper 返回false return false } }) Stack() { ForEach(this.contentIndexArray, (item: number) => { Stack() { Text(this.tabArray[item]) .fontSize(30) .fontWeight(FontWeight.Bold) }.width('100%') .height('100%') .backgroundColor(this.colorArray[item]) .visibility(this.state.currentIndex === item ? Visibility.Visible : Visibility.Hidden) .transition(TransitionEffect.scale({x:0,y:0}).animation({duration:300})) }) }.width('100%') .layoutWeight(1) } .height('100%') .width('100%') .padding({ top: 10 }) } ``` ### 接口说明 #### ScrollableTabRow | 名称 | 类型 | 是否必填 | 说明 | |------------------|-------------------------------------------|------|-------------------------------------------------------------------------------| | array | Object[] | 是 | 标签数组(因鸿蒙ArkTS自定义组件不支持泛型使用Object[]) | | state | ScrollableTabRowState | 是 | ScrollableTabRow组件的状态管理对象,注意:建议一个ScrollableTabRowState只绑定一个ScrollableTabRow组件 | | itemBuilder | (item: Object, index: number) => void | 否 | 自定义标签页构建器,未设置时使用默认Text标签 | | keyGenerator | ((item: Object, index: number) => string) | 否 | 自定义键值的生成规则函数,默认为undefined | | itemPadding | Padding \| Length \| LocalizedPadding | 否 | 标签项的填充距离,默认值{left: 8,right: 8,top: 5,bottom: 5} | | itemHeight | Length | 否 | 标签项高度,默认'auto' | | itemAlign | Alignment | 否 | 标签内容对齐方式,默认Alignment.Center | | fontSize | Length | 否 | 默认标签字号(仅当未设置itemBuilder时生效),默认16 | | fontWeight | number | 否 | 默认字体粗细(未设置itemBuilder时生效),默认400:FontWeight.Normal | | selectFontWeight | number | 否 | 选中标签字体粗细(未设置itemBuilder时生效),默认500:FontWeight.Medium | | fontColor | ResourceColor | 否 | 默认文字颜色(未设置itemBuilder时生效),默认$r('sys.color.font_secondary') | | selectFontColor | ResourceColor | 否 | 选中文字颜色(未设置itemBuilder时生效),默认$r('sys.color.font_emphasize') | | fontColorAnim | boolean | 否 | 是否启用文字颜色插值动画(未设置itemBuilder时生效,且fontColor和selectFontColor为number类型),默认true | | selectScale | number | 否 | 选中标签的缩放比例,默认1 | | barMode | BarMode | 否 | 标签栏模式(Scrollable可滑动/Fixed不可滑动),默认Scrollable | | rowHeight | Length | 否 | 标签行高度,默认'auto' | | rowVerticalAlign | VerticalAlign | 否 | 标签行交叉轴对齐方式,默认VerticalAlign.Center | | rowPadding | NumberPadding | 否 | 标签行内边距(仅支持数值类型),默认{ left: 8, right: 8 } | | rowClip | boolean | 否 | 是否启用行内容裁剪,默认false | | fadingEdgeLength | LengthMetrics \| undefined | 否 | 边缘渐隐长度(仅API≥14生效),默认undefined | | edgeEffect | EdgeEffect | 否 | 设置边缘滑动效果,默认 EdgeEffect.Spring | | indicatorBuilder | () => void | 否 | 自定义指示器构建器,未设置时使用默认样式 | | showIndicator | boolean | 否 | 是否显示指示器,默认true | | indicatorZIndex | number | 否 | 指示器的Z轴层级,值越大越靠前 | | indicatorAlign | VerticalAlign | 否 | 指示器垂直对齐方式,默认VerticalAlign.Bottom | | indicatorPercent | number | 否 | 指示器宽度占标签项的比例,默认0.6 | | indicatorHeight | number | 否 | 指示器高度,默认3 | | indicatorColor | ResourceColor | 否 | 指示器颜色,默认$r('sys.color.brand') | | animOptions | AnimaOptions \| undefined | 否 | 动画的duration和动画的插值曲线,默认 {duration:200 easing :'linear' } | | onTabClick | (item: Object, val: number) => boolean | 否 | 标签点击事件,调用swiper的changeIndex(index, true)返回true,其他都返回false,默认直接返回false | #### ScrollableTabRowState | 名称 | 类型/签名 | 说明 | |---------------|-------------------------------------------------------------------------------------------------|------------------------------------------------------| | constructor | (fraction?: number) => void | 构造函数,可传入初始fraction值 | | fraction | number | 当前选中标签的小数形式索引(例如tab页面滑动到0和1的中间,返回的就是0.5;1和2的中间就是1.5) | | currentIndex | number | 获取当前选中标签的整数索引 | | progress | number | 获取当前标签切换的过渡进度值(范围0-0.9999999999) | | isScrollRight | boolean | 判断是否向右滚动 | | setFraction | (proxy: SwiperContentTransitionProxy) => void | 与Swiper组件联动的核心方法,根据代理对象更新fraction值 | | lerpArgbColor | (index: number, normalColor: number, selectColor: number,isSkipMiddle:boolean = true) => number | ARGB颜色插值计算,支持左右相邻标签的颜色过渡效果(需严格使用ARGB格式) | | lerpColor | (index: number, normalColor: number, selectColor: number,isSkipMiddle:boolean = true) => number | 颜色插值计算,自动处理RGB颜色的透明度补全(推荐常规使用) | | lerp | (index: number, normal: number, select: number,isSkipMiddle:boolean = true) => number | 通用数值插值方法,用于实现字体大小/缩放等属性的平滑过渡 | | lerpInt | (index: number, normal: number, select: number,isSkipMiddle:boolean = true) => number | 整数插值方法 | 关键特性说明: 1. **fraction机制**:通过小数索引值同时表达当前选中项和滑动进度,配合ObservedValue实现UI动态响应 2. **插值计算体系**:提供颜色/数值/整数三类插值方法,支持实现标签选中态的各种过渡动画效果 3. **Swiper联动**:setFraction方法与SwiperContentTransitionProxy深度集成,实现TabRow与页面滑动的同步控制 #### 效果图示例代码&仓库地址 https://gitee.com/jackiehou/scrollable-tab-row #### 开源协议 本项目基于 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) ,请自由的享受和参与开源。