Navigation分栏开发
==============

[Navigation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation)作为一个容器组件，提供了两种布局样式：单栏布局、分栏布局。分栏布局一般适用于宽屏设备，在分栏布局下，导航栏（navBar）会固定显示， 子页面（NavDestination）通过导航控制器（NavPathStack）切换显示， 在导航栏和子页面之间有一条分割线， 可以通过分割线拖拽控制左右显示的比例。架构图详见[Navigation基础架构介绍](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-architecture)。

#### 分栏相关接口介绍

#### \[h2\]mode

[mode](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#mode9)属性用于控制Navigation的显示模式，有四种模式：单栏，分栏，自适应，根据高宽比自适应。

**图1** 单栏（NavigationMode.Stack）效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/44/v3/aR2pd716QOuC2oC_79XHqw/zh-cn_image_0000002594667824.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=D0B717DD0DCFFA1AC1C13373FFE111E6B7D4489F26606BF5CEC6A85101191588)

**图2** 分栏（NavigationMode.Split）效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/27/v3/0z4yyHI1Q4mFx6MWLOwTzw/zh-cn_image_0000002594827752.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=93D21DE27398BE9C8CA1D50931057091E91902BEBADE4E8CFD233F7EE400AA99)

**图3** 自适应（NavigationMode.Auto）效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/72/v3/poPvBYiQQKmvCc57s2eEmw/zh-cn_image_0000002625187199.gif?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=7E35B98D27968F582ADC88DBECDCD4808583556B1904AE6CD913733895A31D32)

**图4** 根据高宽比自适应（NavigationMode.AUTO\_WITH\_ASPECT\_RATIO）效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/03/v3/Gq0aKhRSRhW2uYAFZVWfBg/zh-cn_image_0000002625107343.gif?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=AE8BE9429B48C32DA60C436E0C2289E0949DA27436E3230EB7C9F732B4696340)

#### \[h2\]navBarPosition

[navBarPosition](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#navbarposition9)用于控制导航栏显示的位置，用navBarPosition控制导航栏显示位置时，会被系统语言所影响。比如，在以汉语、英语为代表的LTR语言体系下，NavBarPosition.Start指代的是导航栏出现在左侧，而在以阿拉伯语为代表的RTL语言体系下，NavBarPosition.Start则指代导航栏出现在右侧。类似的效果也出现在NavBarPosition.End上。

**NavBarPosition.Start**

**图4** 系统语言为LTR时NavBarPosition.Start效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/8b/v3/AvvmZmAHQz2kRjJdvGK4JA/zh-cn_image_0000002594667826.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=BB7BFD3E1D54C6A446BF601034A295A1F6481D2DD49EFB1015D79F79A52E32B6)

**图5** 系统语言为RTL时NavBarPosition.Start效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d8/v3/NCvfiFEtRa-QXPxoh7i4Lw/zh-cn_image_0000002594827754.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=8D968A681D266E3970DBAC6DF4D823221FF23A48E4D90F61574313961B1B5EE4)

**NavBarPosition.End**

**图6** 系统语言为LTR时NavBarPosition.End效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/7d/v3/cAYBNAIdQySBQOGTweIE5Q/zh-cn_image_0000002625187201.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=D37DC307162C57DCB1F95451E2EB6FF47E550AB95C62EF3FEE2CC4642BBA2561)

**图7** 系统语言为RTL时NavBarPosition.End效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/71/v3/FOnXiLnERriOc63iGCxYiA/zh-cn_image_0000002625107345.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=0FCEBBA471B25B3D7C4C7A332075ED087EAA4AFD0CF76D0C26BF95C337A2B30A)

#### \[h2\]enableDragBar

[enableDragBar](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#enabledragbar14)用于控制是否显示分栏的拖动按钮。

**图8** enableDragBar为false效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b5/v3/a23ShccGSCOv9nOjFL7EwA/zh-cn_image_0000002594667828.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=78FBC84705F503C44E6FEF011569DC8EFAD5F244E0D3763819A4F9867A901C55)

**图9** enableDragBar为true

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/d2/v3/TiW_mlFVR9mXZoB0Fb4tlA/zh-cn_image_0000002594827756.png?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=1619FC8AF971B6A207B0A5DFCC29EE79CCC87C0AF8230C863DE3F8580465235A)

#### \[h2\]navBarWidth

[navBarWidth](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#navbarwidth9)用于控制导航栏的宽度。

#### \[h2\]navBarWidthRange

[navBarWidthRange](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#navbarwidthrange10)用于设置导航栏宽度可调整的范围。

#### \[h2\]minContentWidth

[minContentWidth](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#mincontentwidth10)用于控制分栏子页的最小宽度；分栏模式导航栏和子页中间会有一个分割线，在可调范围内，用户可以通过拖动分割线来调整导航栏和子页的显示大小。

#### \[h2\]hideNavBar

[hideNavBar](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#hidenavbar9)用于控制导航栏的显示状态，默认值为false。如果同时将mode配置为NavigationMode.Split且hideNavBar设置为true，则实际效果会显示为单栏。

#### \[h2\]enableModeChangeAnimation

[enableModeChangeAnimation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#enablemodechangeanimation15)用于控制是否开启单双栏切换的动画，默认开启。

#### \[h2\]splitPlaceholder

[splitPlaceholder](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation#splitplaceholder20)用于设置分栏模式下内容区的默认占位页。分栏模式在默认情况下，栈中没有页面时内容区展示空白，可使用此接口设置此区域的UI布局。

需要注意的是，占位页仅作为UI展示页，仅分栏模式空栈的情况下才展示，不受路由栈管理也不可获焦和响应事件。

#### 分栏开发示例

以开发一个新闻app的demo来演示如何使用Navigation分栏相关接口。

1.  新闻主页内容会放到左侧NavBar中，其中内容是一个新闻列表，用户点击每一条新闻标题时，右边会push一个详情页，用来展示新闻的信息。
    
2.  给左侧NavBar设置一个宽度范围，右侧子页区域也设置一个最小宽度。
    

配置的路由表：

{
  "routerMap": \[
    {
      "name": "NewsDetail",
      "pageSourceFile": "src/main/ets/pages/navigation/splitmode/NewsDetail.ets",
      "buildFunction": "NewsDetailPageBuilder",
      "data": {
        "description": "this is DetailPageA"
      }
    }
  \]
}

子页代码：

// 自定义的参数类型，用于在push页面时给子页传递参数
export class NewsItem {
  public title: string;
  public overview: string;
  public content: string;

  constructor(title: string, overview: string, content: string) {
    this.title = title;
    this.overview = overview;
    this.content = content;
  }
}

@Builder
export function NewsDetailPageBuilder() {
  NewsDetail()
}

@Component
struct NewsDetail {
  @State title: string = '';
  @State content: string = '';

  build() {
    NavDestination() {
      Column() {
        Text(this.content)
      }
    }
    .title(this.title)
    .backgroundColor('#fff6e3c8')
    .onReady((ctx: NavDestinationContext) => {
      // 在onReady生命周期拿到传来的页面参数
      let param = ctx.pathInfo.param as NewsItem;
      this.title = param?.title;
      this.content = param?.content;
    })
  }
}

主页代码：

import { NewsItem } from './NewsDetail'

@Component
struct NewsHome {
  private newsItemArray: Array<NewsItem> = \[\];
  private stack: NavPathStack | undefined = undefined;

  aboutToAppear(): void {
    // 这里省略了从网络获取新闻信息的过程
    for (let i = 0; i < 50; i++) {
      this.newsItemArray.push(new NewsItem(\`新闻标题${i + 1}\`, \`新闻概述${i + 1}\`, \`新闻详情${i + 1}\`))
    }
    let info = this.queryNavigationInfo();
    this.stack = info?.pathStack;
  }

  build() {
    List() {
      ForEach(this.newsItemArray, (item: NewsItem, index: number) => {
        ListItem() {
          Column() {
            Text(\`${item.title}\`).margin(15).fontSize(25).fontColor(Color.Black)
            Text(\`${item.overview}\`).fontSize(13).fontColor(Color.Gray)
          }.margin({bottom: 15}).backgroundColor('#eeeeee').width('100%')
          .borderRadius(15).height(120).onClick(() => {
            // 用户点击某一个新闻标签时，就在右侧子页区域push一个NavDestination页面，用来展示新闻详情
            this.stack?.pushPath({name: 'NewsDetail', param: item})
          })
        }.width('100%')
      }, (item: NewsItem, index: number) => {
        return item.title;
      })
    }.width('100%').height('100%').padding(15)
  }
}

@Entry
@Component
struct Index {
  private stack: NavPathStack = new NavPathStack();
  @State navWidth: number = 100;

  build() {
    RelativeContainer() {
      Navigation(this.stack) {
        NewsHome().width('100%').height('100%')
      }
      .mode(NavigationMode.Split)
      .enableDragBar(true)
      .hideNavBar(false)
      .navBarWidthRange(\[100, 700\]) // 指定NavBar区域的宽度范围
      .minContentWidth(100) // 指定子页区域的最小宽度
      .hideTitleBar(true)
      .hideToolBar(true)
      .height('100%')
      .width(\`${this.navWidth}%\`)
      .alignRules({
        top: { anchor: '\_\_container\_\_', align: VerticalAlign.Top },
        left: { anchor: '\_\_container\_\_', align: HorizontalAlign.Start }
      })
    }
  }
}

**图10** 运行效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a7/v3/STgX29EAQoC8Lm4QdEDLIA/zh-cn_image_0000002625187203.gif?HW-CC-KV=V1&HW-CC-Date=20260612T073301Z&HW-CC-Expire=86400&HW-CC-Sign=BBEC207489BE6284AC1E270458DB3703060C9BE3969554B7EF115878FFC75782)