• Home
Name Date Size #Lines LOC

..--

AppScope/06-May-2025-3432

casesfeature/tabcontentoverflow/06-May-2025-1,7791,721

entry/06-May-2025-536501

hvigor/06-May-2025-3736

.gitignoreD06-May-2025133 1212

README.mdD06-May-20258.7 KiB218178

build-profile.json5D06-May-20251.4 KiB6161

code-linter.json5D06-May-2025957 3434

hvigorfile.tsD06-May-2025842 215

oh-package.json5D06-May-2025808 2524

README.md

1# Progress触摸热区增大案例
2
3### 介绍
4
5本示例实现了Progress触摸热区增大,拖动进度条和进度条下方区域都能改变播放进度的功能。
6
7### 效果图预览
8
9![](./casesfeature/tabcontentoverflow/tabcontentoverflow.gif)
10
11### 使用说明
12
131. 点击播放按钮进行视频播放,按住进度条按钮和进度条下方区域可以拖动进度条,更改视频播放进度。
14
15### 实现思路
16
17原生的Tabs组件,tabContent内容无法在tabBar上显示。本案例实现tabContent内容可以在tabBar上显示并且tabBar可以响应滑动事件的功能
18主要是通过将Tabs组件的barHeight设置为0,重新自定义tabBar。 将TabContent的内容分为上下两部分,上半部高度为100% - 60vp,存放video组件,
19下部分高度为60vp,存放进度条。将Tabs组件的zIndex属性设置为2,tabContent的视图就可以堆叠在自定义tabBar之上。再设置hitTestBehavior属性
20使被覆盖的tabBar可以响应点击事件。这样就实现tabBar可以响应滑动事件并且tabBar可以响应点击事件的效果。
21
221. 创建Tabs组件,将barHeight设置为0。
23
24```typescript
25Tabs({ index: this.index, controller: this.tabsController }) {
26   ...
27}
28// TODO: 知识点:将zIndex设置为2,TabContent将在tabBar之上,显示的效果就是TabContent外溢的部分在tabBar上。
29.zIndex(CONFIGURATION.TABCONTENTOVERFLOWZINDEX)
30.scrollable(false)
31.barHeight($r('app.integer.tabcontentoverflow_tabs_barheight'))
32.animationDuration(CONFIGURATION.TABCONTENTOVERFLOWTABSDURATION)
33.onChange((index: number) => {
34   this.index = index;
35})
36// TODO: 知识点:hitTestBehavior属性可以实现在复杂的多层级场景下,一些组件能够响应手势和事件,而一些组件不能响应手势和事件。HitTestMode.Transparent的效果为,自身响应触摸测试,不会阻塞兄弟节点的触摸测试。
37.hitTestBehavior(HitTestMode.Transparent)
38.id('tabs')
39.alignRules({
40   top: { anchor: STRINGCONFIGURATION.TABCONTENTOVERFLOWCONTAINER, align: VerticalAlign.Top },
41   left: { anchor: STRINGCONFIGURATION.TABCONTENTOVERFLOWCONTAINER, align: HorizontalAlign.Start },
42})
43```
442. 创建自定义tabBar。
45
46```typescript
47 Row() {
48   ForEach(this.tabArray, (item: string, index: number) => {
49      Column() {
50         Image(this.index === index ? $r(this.imageClickArray[index]) : $r(this.imageArray[index]))
51            .width($r('app.integer.tabcontentoverflow_row_column_image_width'))
52            .height($r('app.integer.tabcontentoverflow_row_column_image_height'))
53         Text($r(item))
54            .fontSize($r('app.integer.tabcontentoverflow_row_column_text_font_size'))
55            .fontColor(this.index === index ? $r('app.color.tabcontentoverflow_click_color') : $r('app.color.tabcontentoverflow_white'))
56      }
57      .width($r('app.integer.tabcontentoverflow_row_column_width'))
58         .margin({ top: $r('app.integer.tabcontentoverflow_margin_samll') })
59         // 为将底部视图扩展到非安全区域,可将原本60vp的高度设置为100vp。
60         .height($r('app.integer.tabcontentoverflow_row_column_height'))
61         .onClick(() => {
62            this.index = index;
63            this.tabsController.changeIndex(this.index);
64         })
65   })
66 }
67 .offset({
68    y: $r('app.integer.tabcontentoverflow_row_offset')
69 })
70 .width($r('app.string.tabcontentoverflow_full_size'))
71 // 扩展至所有非安全区域
72 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
73 .backgroundColor($r('app.color.tabcontentoverflow_row_background'))
74 .justifyContent(FlexAlign.SpaceAround)
75 .id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_TABBAR)
76 .alignRules({
77    top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: VerticalAlign.Bottom },
78    left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start },
79 })
80```
81
823. 将TabContent的内容分为上下两部分,上半部高度为100% - 60vp,存放video组件,下部分高度为60vp,存放进度条,设置滑动手势响应事件。
83
84```typescript
85RelativeContainer()
86{
87   Video({
88      ...
89   })
90   .height($r('app.string.tabcontentoverflow_video_height'))
91   ...
92
93   RelativeContainer() {
94   Text()
95      ...
96   Text()
97      ...
98   Text()
99      ...
100}
101.id(STRINGCONFIGURATION.TABCONTENT_OVERFLOW_RELATIVE_CONTAINER)
102.alignRules({
103   top: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_VIDEO, align: VerticalAlign.Bottom },
104   left: { anchor: STRINGCONFIGURATION.TABCONTENT_OVERFLOW_CONTAINER, align: HorizontalAlign.Start },
105})
106.width(this.screenW)
107.height($r('app.integer.tabcontentoverflow_tabbar_height'))
108// 左右拖动触发该手势事件
109.gesture(
110   PanGesture(this.panOption)
111      .onActionStart(() => {
112         ...
113      })
114      /**
115       * TODO: 性能知识点: onActionUpdate是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。
116       * 优化系统使用,减少冗余操作:参考性能优化指南
117       */
118      .onActionUpdate((event: GestureEvent) => {
119         ...
120      })
121      .onActionEnd(() => {
122         ...
123      })
124)
125}
126```
127
1284. 将Tabs组件的zIndex属性设置为2,tabContent的视图就可以堆叠在自定义tabBar之上。
129
130```typescript
131Tabs({ index: this.index, controller: this.tabsController }) {
132   TabContent() {
133      ...
134   }
135   ...
136
137   TabContent() {
138      this.videoTabContent();
139   }
140
141   TabContent() {
142      ...
143   }
144   ...
145
146   TabContent() {
147      ...
148   }
149   ...
150}
151// TODO: 知识点:将zIndex设置为2,TabContent将在tabBar之上,显示的效果就是TabContent外溢的部分在tabBar上。
152.zIndex(CONFIGURATION.TABCONTENT_OVERFLOW_ZINDEX)
153...
154```
1555. 再设置hitTestBehavior属性使被覆盖的自定义的tabBar可以响应点击事件。
156   源码参考[TabContentOverFlow.ets](casesfeature/tabcontentoverflow/src/main/ets/mainpage/TabContentOverFlow.ets)。
157
158```typescript
159Tabs({ index: this.index, controller: this.tabsController }) {
160   ...
161}
162// TODO: 知识点:hitTestBehavior属性可以实现在复杂的多层级场景下,一些组件能够响应手势和事件,而一些组件不能响应手势和事件。HitTestMode.Transparent的效果为,自身响应触摸测试,不会阻塞兄弟节点的触摸测试。
163.hitTestBehavior(HitTestMode.Transparent)
164```
165
166### 工程结构&模块类型
167
168```
169   dragtoswitchpictures                             // har包
170   |---common
171   |   |---Constants.ets                            // 常量类
172   |---mainpage
173   |   |---TabContentOverFlow.ets                   // 主页面
174   |---view
175   |   |---Side.ets                                 // 视频信息以及顶部视图
176```
177
178### 高性能知识点
179
180本例使用了onActionUpdate函数。该函数是系统高频回调函数,避免在函数中进行冗余或耗时操作,例如应该减少或避免在函数打印日志,会有较大的性能损耗。
181
182界面嵌套带来了渲染和计算的大量开销,造成性能的衰退。本例使用扁平化布局优化嵌套层级,建议采用相对布局RelativeContainer进行扁平化布局,有效减少容器的嵌套层级,减少组件的创建时间。
183
184### 参考资料
185
186[Tabs组件文档](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-tabs.md)
187
188[ZIndex属性说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-z-order.md)
189
190[优化布局性能指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/performance/reduce-view-nesting-levels.md)
191
192[相对定位容器文档](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md)
193
194[应用性能优化概览文档](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/performance/performance-overview.md)
195
196[hitTestBehavior属性说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-universal-attributes-hit-test-behavior.md)
197
198[setWindowSystemBarProperties属性说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-window.md#setwindowsystembarproperties9)
199
200### 约束与限制
201
2021.本示例仅支持在标准系统上运行。
203
2042.本示例需要使用DevEco Studio 5.0.0 Release 才可编译运行。
205
2063.如没有外网权限配置了内部仓可能导致casesfeature中的MP4资源不可用,可从gitee中下载该MP4资源文件进行替换。
207
208### 下载
209
210如需单独下载本工程,执行如下命令:
211```
212git init
213git config core.sparsecheckout true
214echo /code/UI/TabContentTouchHotZone > .git/info/sparse-checkout
215git remote add origin https://gitee.com/openharmony/applications_app_samples.git
216git pull origin master
217```
218