1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BaseInterface } from '../model/BaseInterface'; 17import { baseBuilder } from './BasePage'; 18import { CustomAnimationTabController } from '../model/CustomAniamtionTabController'; 19import { CustomAnimationTabConfigure } from './CustomAnimationTabConfigure' 20import { dyEffectBuilder } from './DyEffectPage'; 21import { IndicatorBarAttribute } from '../model/IndicatorBarAttribute'; 22import { nativeBuilder } from './NativePage'; 23import { otherBuilder } from './OtherPage'; 24import { thirdPartyBuilder } from './ThirdPartyPage'; 25import { TabBarItemInterface } from '../model/TabBarItemInterface'; 26import { TabBarAttribute } from '../model/TabBarAttribute'; 27import { TabInfo } from '../model/TabInfo'; 28import { uiBuilder } from './UIPage'; 29import { MyAnimationAttribute } from './MyAnimationAttribute'; 30import { SizeMode } from '../model/SizeMode'; 31import { CustomAnimationTab } from '../utils/CustomAnimationTab'; 32import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; 33 34/** 35 * 功能说明: 本示例介绍使用List、Text等组件,以及animateTo等接口实现自定义Tab效果 36 * 37 * 推荐场景: 需要自定义动效的tab场景 38 * 39 * 核心组件: 40 * 1. CustomAnimationTab: 自定义动效tab构建组件 41 * 2. AnimationAttribute: 动效属性,可通过继承扩展动效属性 42 * 3. TabInfo: 设置TabBar的标题、TabContent以及TabBar样式的类 43 * 4. CustomAnimationTabController: 自定义动效Tab控制器,用于控制自定义动效Tab组件进行页签切换 44 * 5. IndicatorBarAttribute: 设置背景条属性 45 * 6. TabBarAttribute: 设置页签条属性 46 * 7. Scroller: 页签条滚动控制器 47 * 48 * 实现步骤: 49 * 1. 数据准备: 首先构建一个TabInfo数组,然后向其中传入对应的内容 50 * @example 51 * this.tabsInfo = [ 52 new TabInfo(CustomAnimationTabConfigure.DEFAULT_BASE_TAB, wrapBuilder(baseBuilder), wrapBuilder(tabBar)), 53 new TabInfo(CustomAnimationTabConfigure.DEFAULT_UI_TAB, wrapBuilder(uiBuilder), wrapBuilder(tabBar)), 54 new TabInfo(CustomAnimationTabConfigure.DEFAULT_DYEFFECT_TAB, wrapBuilder(dyEffectBuilder), wrapBuilder(tabBar)), 55 new TabInfo(CustomAnimationTabConfigure.DEFAULT_THIRTYPARTY_TAB, wrapBuilder(thirdPartyBuilder), 56 wrapBuilder(tabBar)), 57 new TabInfo(CustomAnimationTabConfigure.DEFAULT_NATIVE_TAB, wrapBuilder(nativeBuilder), wrapBuilder(tabBar)), 58 new TabInfo(CustomAnimationTabConfigure.DEFAULT_OTHER_TAB, wrapBuilder(otherBuilder), wrapBuilder(tabBar)) 59 ] 60 * 2. 动效属性准备: 创建动效属性AnimationAttribute对象,可以通过继承添加额外动效属性 61 * @example 62 * @State animationAttribute: MyAnimationAttribute = new MyAnimationAttribute( 63 * CustomAnimationTabConfigure.INDICATOR_WIDTH, $r('app.color.custom_animation_tab_indicator_color')); 64 * 3. 背景条配置: 背景条可以自行new IndicatorBarAttribute配置,也可以使用已有的背景条配置(目前支持两种: 65 * IndicatorBarAttribute.BACKGROUNDBAR和IndicatorBarAttribute.THINSTRIP) 66 * @example 67 * indicatorBarAttribute: IndicatorBarAttribute = new IndicatorBarAttribute(this.indicatorBar); 68 * 4. 页签条配置 69 * @example 70 * tabBarAttribute: TabBarAttribute = new TabBarAttribute(CustomAnimationTabConfigure.LIST_ITEM_WIDTH); 71 * 5. 自定义动效tab控制器配置 72 * @example 73 * tabController: CustomAnimationTabController = new CustomAnimationTabController(); 74 * 6. 页签条滑动配置 75 * @example 76 * scroller: Scroller = new Scroller(); 77 * 7. 构建自定义动效tab 78 * @example 79 * CustomAnimationTab({ 80 animationAttribute: this.animationAttribute, 81 tabsInfo: this.tabsInfo, 82 indicatorBarAttribute: this.indicatorBarAttribute, 83 tabBarAttribute: this.tabBarAttribute, 84 tabController: this.tabController, 85 scroller: this.scroller 86 }) 87 */ 88@Builder 89function testBuilder() { 90 Column() { 91 } 92 .height('100%') 93 .width('100%') 94 .backgroundColor(Color.Gray) 95} 96 97@Component 98export struct CustomAnimationTabView { 99 // 自定义动效属性,添加了背景条颜色变化 100 @State animationAttribute: MyAnimationAttribute = 101 new MyAnimationAttribute($r('app.color.custom_animation_tab_indicator_color')); 102 // tab数据 103 tabsInfo: TabInfo[] = []; 104 // tabController 105 tabController: CustomAnimationTabController = new CustomAnimationTabController(); 106 // indicatorBar 107 indicatorBarAttribute: IndicatorBarAttribute = new IndicatorBarAttribute(this.indicatorBar, SizeMode.Normal, 0, 0, 108 CustomAnimationTabConfigure.INDICATOR_MAX_LEFT, CustomAnimationTabConfigure.DEFAULT_INDICATOR_EXPAND); 109 // tabBar 110 tabBarAttribute: TabBarAttribute = 111 new TabBarAttribute(CustomAnimationTabConfigure.LIST_ITEM_WIDTH, CustomAnimationTabConfigure.TABBAR_HEIGHT, 112 true, EdgeEffect.Spring, BarPosition.Start); 113 // scroller 114 scroller: Scroller = new Scroller(); 115 116 aboutToAppear(): void { 117 this.tabsInfo = [ 118 new TabInfo(CustomAnimationTabConfigure.DEFAULT_BASE_TAB, wrapBuilder(baseBuilder), wrapBuilder(tabBar)), 119 new TabInfo(CustomAnimationTabConfigure.DEFAULT_UI_TAB, wrapBuilder(uiBuilder), wrapBuilder(tabBar)), 120 new TabInfo(CustomAnimationTabConfigure.DEFAULT_DYEFFECT_TAB, wrapBuilder(dyEffectBuilder), wrapBuilder(tabBar)), 121 new TabInfo(CustomAnimationTabConfigure.DEFAULT_THIRTYPARTY_TAB, wrapBuilder(thirdPartyBuilder), 122 wrapBuilder(tabBar)), 123 new TabInfo(CustomAnimationTabConfigure.DEFAULT_NATIVE_TAB, wrapBuilder(nativeBuilder), wrapBuilder(tabBar)), 124 new TabInfo(CustomAnimationTabConfigure.DEFAULT_OTHER_TAB, wrapBuilder(otherBuilder), wrapBuilder(tabBar)) 125 ] 126 } 127 128 build() { 129 RelativeContainer() { 130 this.body(); 131 } 132 .height('100%') 133 .width('100%') 134 } 135 136 @Builder 137 body() { 138 Column() { 139 /** 140 * 构建自定义动效Tab 141 * indicatorBarAttribute: 背景条属性 142 * tabsInfo: tab数据源 143 * tabBarAttribute: 页签条属性 144 * animationAttribute: 动效属性 145 * tabController: 自定义动效tab控制器 146 * scroller: 页签条滚动控制器 147 */ 148 CustomAnimationTab({ 149 animationAttribute: this.animationAttribute, 150 tabsInfo: this.tabsInfo, 151 indicatorBarAttribute: this.indicatorBarAttribute, 152 tabBarAttribute: this.tabBarAttribute, 153 tabController: this.tabController, 154 scroller: this.scroller 155 }) 156 .height($r('app.string.custom_animation_tab_ninety_percent')) 157 // 更新自定义动效变量——背景条颜色 158 Column() { 159 Button($r('app.string.custom_animation_tab_button_text')) 160 .height($r('app.string.custom_animation_tab_sixty_percent')) 161 .onClick(() => { 162 if ((this.animationAttribute.indicatorBarColor as Resource).id === 163 $r('app.color.custom_animation_tab_indicator_color').id) { 164 this.animationAttribute.indicatorBarColor = Color.Yellow; 165 } else if (this.animationAttribute.indicatorBarColor === Color.Yellow) { 166 this.animationAttribute.indicatorBarColor = $r('app.color.custom_animation_tab_indicator_color'); 167 } 168 }) 169 } 170 .justifyContent(FlexAlign.Center) 171 .height($r('app.string.custom_animation_tab_ten_percent')) 172 .width($r('app.string.custom_animation_tab_one_hundred_percent')) 173 } 174 .height($r('app.string.custom_animation_tab_one_hundred_percent')) 175 .width($r('app.string.custom_animation_tab_one_hundred_percent')) 176 } 177 178 @Builder 179 indicatorBar($$: BaseInterface) { 180 Column() 181 .height($r('app.string.custom_animation_tab_one_hundred_percent')) 182 .width($r('app.string.custom_animation_tab_one_hundred_percent'))// 绑定自定义动效属性 183 .backgroundColor(this.animationAttribute.indicatorBarColor) 184 .borderRadius($r('app.float.custom_animation_tab_indicator_border_radius')) 185 } 186} 187 188// tabBar样式 189@Builder 190function tabBar($$: TabBarItemInterface) { 191 Column() { 192 Image($r('app.media.return_home_fill')) 193 .height(20) 194 .width(20) 195 .objectFit(ImageFit.Contain) 196 Text($$.title) 197 .fontSize($$.curIndex === $$.index ? $r('app.float.custom_animation_tab_list_select_font_size') : 198 $r('app.float.custom_animation_tab_list_unselect_font_size')) 199 .fontColor($r('app.color.custom_animation_tab_list_font_color')) 200 .fontWeight($$.curIndex === $$.index ? FontWeight.Bold : FontWeight.Medium) 201 .textAlign(TextAlign.Center) 202 } 203}