1# 导航转场
2
3
4导航转场是页面的路由转场方式,也就是一个界面消失,另外一个界面出现的动画效果。开发者也可以自定义导航转场的动画效果,具体请参考Navigation[示例3](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#示例3)。
5
6
7导航转场推荐使用[Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md)组件实现,可搭配[NavDestination](../reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md)组件实现导航功能。
8
9
10完整的代码示例和效果如下。
11
12## 创建导航页
13实现步骤为:
14
151.使用Navigation创建导航主页,并创建路由栈NavPathStack以此来实现不同页面之间的跳转。
16
172.在Navigation中增加List组件,来定义导航主页中不同的一级界面。
18
193.在List内的组件添加onClick方法,并在其中使用路由栈NavPathStack的pushPathByName方法,使组件可以在点击之后从当前页面跳转到输入参数name在路由表内对应的页面。
20```ts
21//PageOne.ets
22@Entry
23@Component
24struct NavigationDemo {
25  @Provide('pathInfos') pathInfos: NavPathStack = new NavPathStack();
26  private listArray: Array<string> = ['WLAN', 'Bluetooth', 'Personal Hotpot', 'Connect & Share'];
27
28  build() {
29    Column() {
30      Navigation(this.pathInfos) {
31        TextInput({ placeholder: '输入关键字搜索' })
32          .width('90%')
33          .height(40)
34          .margin({ bottom: 10 })
35
36        // 通过List定义导航的一级界面
37        List({ space: 12, initialIndex: 0 }) {
38          ForEach(this.listArray, (item: string) => {
39            ListItem() {
40              Row() {
41                Row() {
42                  Text(`${item.slice(0, 1)}`)
43                    .fontColor(Color.White)
44                    .fontSize(14)
45                    .fontWeight(FontWeight.Bold)
46                }
47                .width(30)
48                .height(30)
49                .backgroundColor('#a8a8a8')
50                .margin({ right: 20 })
51                .borderRadius(20)
52                .justifyContent(FlexAlign.Center)
53
54                Column() {
55                  Text(item)
56                    .fontSize(16)
57                    .margin({ bottom: 5 })
58                }
59                .alignItems(HorizontalAlign.Start)
60
61                Blank()
62
63                Row()
64                  .width(12)
65                  .height(12)
66                  .margin({ right: 15 })
67                  .border({
68                    width: { top: 2, right: 2 },
69                    color: 0xcccccc
70                  })
71                  .rotate({ angle: 45 })
72              }
73              .borderRadius(15)
74              .shadow({ radius: 100, color: '#ededed' })
75              .width('90%')
76              .alignItems(VerticalAlign.Center)
77              .padding({ left: 15, top: 15, bottom: 15 })
78              .backgroundColor(Color.White)
79            }
80            .width('100%')
81            .onClick(() => {
82              this.pathInfos.pushPathByName(`${item}`, '详情页面参数')//将name指定的NaviDestination页面信息入栈,传递的参数为param
83            })
84          }, (item: string): string => item)
85        }
86        .listDirection(Axis.Vertical)
87        .edgeEffect(EdgeEffect.Spring)
88        .sticky(StickyStyle.Header)
89        .chainAnimation(false)
90        .width('100%')
91      }
92      .width('100%')
93      .mode(NavigationMode.Auto)
94      .title('设置') // 设置标题文字
95    }
96    .size({ width: '100%', height: '100%' })
97    .backgroundColor(0xf4f4f5)
98  }
99}
100```
101## 创建导航子页
102导航子页1实现步骤为:
103
1041.使用NavDestination,来创建导航子页CommonPage。
105
1062.创建路由栈NavPathStack并在onReady时进行初始化,获取当前所在的页面栈,以此来实现不同页面之间的跳转。
107
1083.在子页面内的组件添加onClick,并在其中使用路由栈NavPathStack的pop方法,使组件可以在点击之后弹出路由栈栈顶元素实现页面的返回。
109```ts
110//PageOne.ets
111
112@Builder
113export function MyCommonPageBuilder(name: string, param: string) {
114  MyCommonPage({ name: name, value: param })
115}
116
117@Component
118export struct MyCommonPage {
119  pathInfos: NavPathStack = new NavPathStack();
120  name: String = '';
121  @State value: String = '';
122
123  build() {
124    NavDestination() {
125      Column() {
126        Text(`${this.name}设置页面`)
127          .width('100%')
128          .fontSize(20)
129          .fontColor(0x333333)
130          .textAlign(TextAlign.Center)
131          .textShadow({
132            radius: 2,
133            offsetX: 4,
134            offsetY: 4,
135            color: 0x909399
136          })
137          .padding({ top: 30 })
138        Text(`${JSON.stringify(this.value)}`)
139          .width('100%')
140          .fontSize(18)
141          .fontColor(0x666666)
142          .textAlign(TextAlign.Center)
143          .padding({ top: 45 })
144        Button('返回')
145          .width('50%')
146          .height(40)
147          .margin({ top: 50 })
148          .onClick(() => {
149            //弹出路由栈栈顶元素,返回上个页面
150            this.pathInfos.pop();
151          })
152      }
153      .size({ width: '100%', height: '100%' })
154    }.title(`${this.name}`)
155    .onReady((ctx: NavDestinationContext) => {
156      //NavDestinationContext获取当前所在的页面栈
157      this.pathInfos = ctx.pathStack;
158    })
159
160  }
161}
162
163
164```
165导航子页2实现步骤为:
166
1671.使用NavDestination,来创建导航子页SharePage。
168
1692.创建路由栈NavPathStack并在onReady时进行初始化,获取当前所在的页面栈,以此来实现不同页面之间的跳转。
170
1713.在子页面内的组件添加onClick,并在其中使用路由栈NavPathStack的pushPathByName方法,使组件可以在点击之后从当前页面跳转到输入参数name在路由表内对应的页面。
172```ts
173//PageTwo.ets
174@Builder
175export function MySharePageBuilder(name: string, param: string) {
176  MySharePage({ name: name })
177}
178
179@Component
180export struct MySharePage {
181  pathInfos: NavPathStack = new NavPathStack();
182  name: String = '';
183  private listArray: Array<string> = ['Projection', 'Print', 'VPN', 'Private DNS', 'NFC'];
184
185  build() {
186    NavDestination() {
187      Column() {
188        List({ space: 12, initialIndex: 0 }) {
189          ForEach(this.listArray, (item: string) => {
190            ListItem() {
191              Row() {
192                Row() {
193                  Text(`${item.slice(0, 1)}`)
194                    .fontColor(Color.White)
195                    .fontSize(14)
196                    .fontWeight(FontWeight.Bold)
197                }
198                .width(30)
199                .height(30)
200                .backgroundColor('#a8a8a8')
201                .margin({ right: 20 })
202                .borderRadius(20)
203                .justifyContent(FlexAlign.Center)
204
205                Column() {
206                  Text(item)
207                    .fontSize(16)
208                    .margin({ bottom: 5 })
209                }
210                .alignItems(HorizontalAlign.Start)
211
212                Blank()
213
214                Row()
215                  .width(12)
216                  .height(12)
217                  .margin({ right: 15 })
218                  .border({
219                    width: { top: 2, right: 2 },
220                    color: 0xcccccc
221                  })
222                  .rotate({ angle: 45 })
223              }
224              .borderRadius(15)
225              .shadow({ radius: 100, color: '#ededed' })
226              .width('90%')
227              .alignItems(VerticalAlign.Center)
228              .padding({ left: 15, top: 15, bottom: 15 })
229              .backgroundColor(Color.White)
230            }
231            .width('100%')
232            .onClick(() => {
233              this.pathInfos.pushPathByName(`${item}`, '页面设置参数')
234            })
235          }, (item: string): string => item)
236        }
237        .listDirection(Axis.Vertical)
238        .edgeEffect(EdgeEffect.Spring)
239        .sticky(StickyStyle.Header)
240        .width('100%')
241      }
242      .size({ width: '100%', height: '100%' })
243    }.title(`${this.name}`)
244    .onReady((ctx: NavDestinationContext) => {
245      //NavDestinationContext获取当前所在的页面栈
246      this.pathInfos = ctx.pathStack;
247    })
248  }
249}
250```
251## 创建路由跳转
252实现步骤为:
253
2541.工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"}。
255
2562.route_map.json中配置全局路由表,路由栈NavPathStack可根据路由表中的name将对应页面信息入栈。
257```ts
258{
259  "routerMap" : [
260    {
261      "name" : "WLAN",
262      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
263      "buildFunction" : "MyCommonPageBuilder"
264    },
265    {
266      "name" : "Bluetooth",
267      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
268      "buildFunction" : "MyCommonPageBuilder"
269    },
270    {
271      "name" : "Personal Hotpot",
272      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
273      "buildFunction" : "MyCommonPageBuilder"
274    },
275    {
276      "name" : "Connect & Share",
277      "pageSourceFile"  : "src/main/ets/pages/PageTwo.ets",
278      "buildFunction" : "MySharePageBuilder"
279    },
280    {
281      "name" : "Projection",
282      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
283      "buildFunction" : "MyCommonPageBuilder"
284    },
285    {
286      "name" : "Print",
287      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
288      "buildFunction" : "MyCommonPageBuilder"
289    },
290    {
291      "name" : "VPN",
292      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
293      "buildFunction" : "MyCommonPageBuilder"
294    },
295    {
296      "name" : "Private DNS",
297      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
298      "buildFunction" : "MyCommonPageBuilder"
299    },
300    {
301      "name" : "NFC",
302      "pageSourceFile"  : "src/main/ets/pages/PageOne.ets",
303      "buildFunction" : "MyCommonPageBuilder"
304    }
305  ]
306}
307```
308
309![zh-cn_image_0000001588458252](figures/arkts-navigation-transition_1.gif)