HarmonyOS 6.0 Dynamic Navigation Bar: Auto-Hide on Scroll with HdsNavigation
Learn to implement scroll-responsive navigation bars in HarmonyOS 6.0 using HdsNavigation's dynamicHideTitleBar API, with step-by-step configuration, hide modes (SCROLL_UP_TO), offset tuning, blur effect combination, conditional enabling, and debugging techniques for smooth immersive UIs.
Feature Overview: Precise Control Over Each Area
HarmonyOS 6.0.0(20) Beta1 introduces a new dynamic show/hide capability for navigation components, allowing the title bar, status bar, and custom bottom areas to elegantly "breathe" with user scroll interactions. This feature provides three layers of dynamic hiding:
Hide title area : Main title and subtitle area can be hidden, freeing more content space.
Hide status bar : Only takes effect when the title area is already hidden, ensuring visual continuity.
Hide bottom builder : Custom bottom components (e.g., search bars, toolbars) can be hidden.
This layered control mechanism ensures reasonable and coherent interface changes, avoiding abrupt layout jumps.
Implementation Guide: Four Steps to Dynamic Show/Hide
Step 1: Module Import
import { HdsNavigation, HdsNavigationAttribute, BottomBuilderShowType, HideMode } from '@kit.UIDesignKit';Step 2: Build Bottom Component (Optional)
To control bottom area visibility, create a custom bottom builder:
@Builder BottomBuilder() { Column() { Search() .placeholder('Search...') } .width('100%') .height(56) .backgroundColor($r('sys.color.comp_background_tertiary')) }Step 3: Configure Navigation Base Structure
Create an HdsNavigation component with title bar and bottom builder:
@Entry @Component struct SmartNavigationPage { @State currentOffset: number = 0 build() { HdsNavigation() { Scroll() { Column() { // Content area } .onScrollFrameBegin((offset: number) => { this.currentOffset = offset }) } .titleBar({ content: { title: { mainTitle: 'Smart Life', subTitle: 'Explore New Experience' }, bottomBuilder: { builder: (): void => this.BottomBuilder(), height: 56, showType: BottomBuilderShowType.DIRECTLY_SHOW } } }) } }Step 4: Enable Dynamic Show/Hide
Use the dynamicHideTitleBar method to precisely control visibility behavior:
.dynamicHideTitleBar({ hideTitleArea: true, hideBottomBuilder: true, hideStatusBar: false, mode: HideMode.SCROLL_UP_TO, hideOffset: 10 })Core Parameter Deep Dive
1. Hide Mode (HideMode)
The example uses SCROLL_UP_TO mode: hide when scrolling up reaches a specified distance. Other possible modes include: SCROLL_DOWN_TO: Show when scrolling down. AUTO: Automatically determine based on scroll direction.
2. Hide Offset (hideOffset)
Defines the trigger threshold:
Upward scroll distance ≥ 10vp: Start hide animation.
Upward scroll distance < 10vp: Remain visible.
Reverse scroll: Execute show animation.
3. Status Bar Hide Condition
hideStatusBaronly takes effect when hideTitleArea is true. This dependency ensures:
Status bar never hides alone, avoiding visual discontinuity.
Visual changes align with user cognitive habits.
Practical Tips and Best Practices
Tip 1: Combine with Dynamic Blur Style
.titleBar({ style: { scrollEffectOpts: { enableScrollEffect: true, scrollEffectType: ScrollEffectType.COMMON_BLUR, blurEffectiveEndOffset: LengthMetrics.vp(20) } } }) .dynamicHideTitleBar({ hideTitleArea: true, hideOffset: 30, mode: HideMode.SCROLL_UP_TO })Set hideOffset larger than blur completion offset so hiding starts after blur finishes.
Tip 2: Smart Enable Control Logic
.dynamicHideTitleBar(this.shouldEnableDynamicHide() ? { hideTitleArea: true, hideOffset: 15, mode: HideMode.SCROLL_UP_TO } : undefined) shouldEnableDynamicHide(): boolean { return this.contentType === 'article' && this.contentLength > 1000 }Enable dynamic hide only for long articles; disable for short forms.
Tip 3: Smooth Transition Animation Optimization
.onTitleBarVisibilityChange((visible: boolean) => { if (!visible) { this.adjustFloatingActionButton(true) } else { this.adjustFloatingActionButton(false) } })Listen to visibility changes and adjust floating action button position accordingly.
Common Issues and Debugging Advice
Q1: Why doesn't the status bar hide?
Check if hideTitleArea is true (prerequisite).
Confirm device system version ≥ 6.0.0(20) Beta1.
Check for other styles overriding status bar settings.
Q2: Hide animation not smooth?
Ensure scroll component (Scroll/List) performance is optimized.
Check hideOffset value not too small (recommended ≥10vp).
Avoid heavy computations during scroll.
Q3: How to debug show/hide boundaries?
Scroll() { Column() { // Content } .onScrollFrameBegin((offset: number) => { console.log(`Current scroll offset: ${offset}vp`) console.log(`Hide threshold: 10vp`) console.log(`Title bar should ${offset >= 10 ? 'hide' : 'show'}`) }) }Design Philosophy and User Experience
1. Progressive Information Presentation
Dynamic show/hide is not a simple toggle but an information priority management strategy:
User starts scrolling → indicates focus on content → gradually hide navigation elements.
User stops scrolling → may need actions → gradually show navigation elements.
2. Reduce Visual Distraction
In deep consumption scenarios (long reads, image browsing), hiding the navigation bar can:
Increase effective content area by 10%-15%.
Lower visual element complexity.
Improve user focus.
3. Maintain Action Accessibility
Even when the navigation bar is hidden, key actions (back, search) remain accessible via gestures or floating buttons, ensuring functional completeness.
Complete Example Code
import { HdsNavigation, BottomBuilderShowType, HideMode } from '@kit.UIDesignKit'; @Entry @Component struct ArticleReaderPage { @State articleContent: string = '' @Builder ArticleToolbar() { Row() { Button('Favorite').width(80) Button('Share').width(80) Button('Settings').width(80) } .width('100%') .height(48) .justifyContent(FlexAlign.SpaceEvenly) } build() { HdsNavigation() { Scroll() { Text(this.articleContent) .fontSize(16) .lineHeight(24) .padding(20) } .titleBar({ content: { title: { mainTitle: 'Deep Read' }, bottomBuilder: { builder: (): void => this.ArticleToolbar(), height: 48, showType: BottomBuilderShowType.DIRECTLY_SHOW } } }) .dynamicHideTitleBar({ hideTitleArea: true, hideBottomBuilder: true, hideStatusBar: false, mode: HideMode.SCROLL_UP_TO, hideOffset: 12 }) } }Summary
HarmonyOS 6.0's navigation bar dynamic show/hide feature embodies modern mobile UI design philosophy: interfaces should intelligently adapt to user intent rather than remain static. With simple configuration, developers can achieve effects that previously required complex custom code.
Core Value Recap:
Declarative Configuration : Few lines of code enable advanced interaction effects.
Fine-grained Control : Layered management of different navigation area visibility.
Native Performance : System-level support ensures smooth, jank-free animations.
Design Consistency : Complies with HarmonyOS design language specifications.
Recommended for content-consumption, media-browsing, or long-focus applications. It not only elevates visual quality but creates a more humanized, focused user experience. Start now and let your app's navigation bar learn to "breathe", moving gracefully with the user's rhythm.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
51CTO HarmonyOS Developer Community
The HarmonyOS Developer Community is a learning-oriented community for developers to learn, communicate, ask questions, and share.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
