在HarmonyOS应用开发中,当使用渐变导航并嵌套Tabs组件时,列表上滑后列表项无法穿透标题栏区域显示,导致渐变导航的穿透效果失效。
在HarmonyOS应用开发中,渐变导航通常通过设置ScrollEffectType.GRADIENT_BLUR实现列表项滚动时穿透标题栏的视觉效果。Tabs组件常用于实现视图切换,其包含的TabContent组件用于展示具体内容。默认情况下,组件的clip属性为true,会对超出自身边界范围的子组件进行裁剪。更多参考请参见Tabs组件和滚动组件通用属性。
在实现渐变导航穿透效果时,若在导航容器内嵌套了Tabs及TabContent组件,当内部List组件上滑时,ListItem虽然已经进入标题栏区域,但并未穿透标题栏显示出来。排查发现,由于Tabs和TabContent组件默认开启了clip裁剪功能,超出的内容被直接裁剪掉,导致渐变导航的穿透效果无法正常生效。
核心原因:Tabs和TabContent组件的clip属性默认会对超出当前组件范围外的子组件区域进行裁剪。
技术原理解析:渐变导航的穿透效果依赖于子组件能够超出父容器边界进行渲染。当嵌套Tabs时,Tabs和TabContent的默认裁剪行为阻止了内部List内容延伸至标题栏区域,从而表现为渐变导航不工作。
为Tabs和TabContent组件设置clip(false),关闭超出区域的裁剪功能。
- import { HdsNavigation, HdsNavigationTitleMode, ScrollEffectType, TitleBarStyleOptions } from '@hms.hds.hdsBaseComponent';
-
- @Entry
- @Component
- struct Index {
- @State index: number = 0
-
- build() {
- HdsNavigation() {
- Tabs({ index: this.index }) {
- TabContent() {
- FollowListView()
- }
- .clip(false)
- .tabBar(this.TabBuilder(0, '关注'))
- .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
-
- TabContent() {
- FollowListView()
- }
- .tabBar(this.TabBuilder(1, '粉丝'))
- .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
- }
- .clip(false)
- .tabsStyle()
- .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
- }
- .titleMode(HdsNavigationTitleMode.MINI)
- .titleBar({
- enableComponentSafeArea: true,
- content: {
- title: {
- mainTitle: 'Home'
- }
- },
- style: NavDestinationStyle()
- })
- }
-
- @Builder
- TabBuilder(index: number, name: string) {
- }
- }
-
- @Component
- struct FollowListView {
- build() {
- List({ space: 24 }) {
- ForEach([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], (item: number) => {
- ListItem() {
- Text(item + "")
- .padding(16)
- .backgroundColor(Color.Brown)
- .width('100%')
- }
- .height(64)
- }, (item: number) => item + '')
- }
- .width('100%')
- .height('100%')
- .clip(false)
- .cachedCount(3, true)
- .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
- }
- }
-
- export function NavDestinationStyle(): TitleBarStyleOptions {
- return {
- scrollEffectOpts: {
- enableScrollEffect: true,
- scrollEffectType: ScrollEffectType.GRADIENT_BLUR,
- },
- scrollEffectStyle: {
- backgroundStyle: {
- backgroundColor: $r('sys.color.ohos_id_color_background_transparent')
- }
- }
- }
- }
-
- @Extend(Tabs)
- function tabsStyle() {
- .width('100%')
- .height('100%')
- .barHeight(0)
- .barWidth('100%')
- .barOverlap(true)
- .animationDuration(250)
- .barBackgroundBlurStyle(BlurStyle.Regular)
- }