13.ArkUI Navigation的介绍和使用
Entry@Componentbuild() {Column() {Text('页面内容').title('自定义标题').subTitle('副标题').toolBar({items: [// 分享操作},})
·
ArkUI Navigation 组件介绍与使用指南
什么是 Navigation 组件?
Navigation 是 ArkUI 中的导航组件,用于管理页面间的导航和路由。它提供了页面栈管理、导航栏定制、页面切换动画等功能,是构建多页面应用的核心组件。
Navigation 的核心概念
- 页面栈:采用栈结构管理页面,遵循"后进先出"原则
- 导航模式:
NavigationMode.Stack
:栈模式(默认)NavigationMode.Split
:分栏模式(平板等大屏设备)
- 导航栏:可自定义标题栏区域
- 路由:通过路径标识页面,支持参数传递
基本使用方法
简单页面导航
// 首页
@Entry
@Component
struct HomePage {
build() {
Navigation() {
Column() {
Text('首页')
.fontSize(30)
.margin(20)
Button('跳转到详情页')
.onClick(() => {
router.pushUrl({
url: 'pages/DetailPage'
})
})
}
.width('100%')
.height('100%')
}
.title('首页')
}
}
// 详情页
@Component
struct DetailPage {
build() {
Column() {
Text('详情页内容')
.fontSize(30)
.margin(20)
Button('返回')
.onClick(() => {
router.back()
})
}
.width('100%')
.height('100%')
}
}
带参数的页面导航
// 列表页
@Entry
@Component
struct ListPage {
private items: string[] = ['苹果', '香蕉', '橙子', '葡萄']
build() {
Navigation() {
Column() {
ForEach(this.items, (item) => {
Button(item)
.width('80%')
.margin(5)
.onClick(() => {
router.pushUrl({
url: 'pages/DetailPage',
params: { name: item }
})
})
})
}
}
.title('水果列表')
}
}
// 详情页
@Component
struct DetailPage {
@State name: string = ''
onPageShow() {
this.name = router.getParams()?.['name'] || '未知'
}
build() {
Column() {
Text(`您选择了: ${this.name}`)
.fontSize(30)
.margin(20)
}
}
}
高级用法
自定义导航栏
@Entry
@Component
struct CustomNavPage {
build() {
Navigation() {
Column() {
Text('页面内容')
.fontSize(20)
.margin(20)
}
}
.title('自定义标题')
.subTitle('副标题')
.hideBackButton(false)
.toolBar({
items: [
{
icon: $r('app.media.ic_share'),
action: () => {
// 分享操作
}
},
{
icon: $r('app.media.ic_favorite'),
action: () => {
// 收藏操作
}
}
]
})
.navBarWidth('80%')
.navBarPosition(NavBarPosition.Start)
}
}
分栏模式 (Split)
@Entry
@Component
struct SplitNavigationExample {
private menus: string[] = ['首页', '分类', '发现', '我的']
@State selectedIndex: number = 0
build() {
Navigation() {
Column() {
ForEach(this.menus, (menu, index) => {
Button(menu)
.width('100%')
.stateEffect(this.selectedIndex === index)
.onClick(() => {
this.selectedIndex = index
})
})
}
.width('30%')
.backgroundColor('#f5f5f5')
Column() {
if (this.selectedIndex === 0) {
Text('首页内容').fontSize(24)
} else if (this.selectedIndex === 1) {
Text('分类内容').fontSize(24)
} else if (this.selectedIndex === 2) {
Text('发现内容').fontSize(24)
} else {
Text('个人中心').fontSize(24)
}
}
.layoutWeight(1)
.padding(20)
}
.mode(NavigationMode.Split)
.minNavBarWidth(200)
.maxNavBarWidth(300)
}
}
页面切换动画
@Entry
@Component
struct AnimatedNavigation {
build() {
Navigation() {
Column() {
Button('淡入淡出效果')
.onClick(() => {
router.pushUrl({
url: 'pages/DetailPage',
transition: {
type: RouteType.Push,
curve: Curve.EaseInOut,
duration: 300
}
})
})
Button('滑动效果')
.onClick(() => {
router.pushUrl({
url: 'pages/DetailPage',
transition: {
type: RouteType.Push,
slide: SlideEffect.Left
}
})
})
}
}
}
}
实际应用示例
电商应用导航
@Entry
@Component
struct ECommerceApp {
@State currentTab: number = 0
private tabs: string[] = ['首页', '分类', '购物车', '我的']
build() {
Navigation() {
Column() {
// 顶部导航栏
Row() {
ForEach(this.tabs, (tab, index) => {
Button(tab)
.borderRadius(0)
.backgroundColor(this.currentTab === index ? '#ff5500' : '#ffffff')
.fontColor(this.currentTab === index ? Color.White : Color.Black)
.onClick(() => {
this.currentTab = index
})
})
}
.width('100%')
.height(50)
// 内容区域
Column() {
if (this.currentTab === 0) {
HomeTab()
} else if (this.currentTab === 1) {
CategoryTab()
} else if (this.currentTab === 2) {
CartTab()
} else {
ProfileTab()
}
}
.layoutWeight(1)
}
}
.hideToolBar(true)
.hideTitleBar(true)
}
}
@Component
struct HomeTab {
build() {
Scroll() {
Column() {
// 轮播图
Swiper() {
ForEach(['banner1', 'banner2', 'banner3'], (img) => {
Image(img)
.width('100%')
.height(200)
})
}
.indicator(true)
.height(200)
// 商品网格
Grid() {
ForEach(Array.from({ length: 12 }), (_, index) => {
GridItem() {
Column() {
Image(`product_${index + 1}`)
.width(80)
.height(80)
Text(`商品${index + 1}`)
.fontSize(14)
Text('¥99')
.fontColor('#ff5500')
.fontSize(16)
}
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.rowsGap(10)
.columnsGap(10)
.margin(10)
}
}
}
}
新闻应用导航
@Entry
@Component
struct NewsApp {
@State currentChannel: string = '推荐'
private channels: string[] = ['推荐', '热点', '科技', '娱乐', '体育']
build() {
Navigation() {
Column() {
// 频道导航
Scroll({ scrollable: ScrollDirection.Horizontal }) {
Row() {
ForEach(this.channels, (channel) => {
Button(channel)
.margin({ right: 15 })
.stateEffect(this.currentChannel === channel)
.onClick(() => {
this.currentChannel = channel
})
})
}
.padding(10)
}
.scrollBar(BarState.Off)
// 新闻列表
Scroll() {
Column() {
ForEach(Array.from({ length: 10 }), (_, index) => {
Column() {
Text(`【${this.currentChannel}】新闻标题 ${index + 1}`)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 5 })
Text('新闻摘要内容...')
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 10 })
Divider()
}
.margin({ top: 10, left: 15, right: 15 })
.onClick(() => {
router.pushUrl({
url: 'pages/NewsDetail',
params: { id: index + 1 }
})
})
})
}
}
.layoutWeight(1)
}
}
.title('新闻资讯')
.toolBar({
items: [
{
icon: $r('app.media.ic_search'),
action: () => {
router.pushUrl({
url: 'pages/SearchPage'
})
}
}
]
})
}
}
注意事项
-
页面生命周期:
onPageShow
:页面显示时触发onPageHide
:页面隐藏时触发onBackPress
:返回按钮点击时触发(可拦截返回操作)
-
路由管理:
- 使用
router.pushUrl
导航到新页面 - 使用
router.back
返回上一页 - 使用
router.replaceUrl
替换当前页面 - 使用
router.clear
清空页面栈
- 使用
-
性能优化:
- 避免在导航栏中使用复杂组件
- 对于不常变化的页面考虑使用缓存
- 合理使用分栏模式提升大屏设备体验
-
兼容性考虑:
- 分栏模式在大屏设备上效果更好
- 确保导航结构在小屏设备上也能良好工作
Navigation 组件是构建复杂应用导航系统的基础,合理使用可以创建直观、高效的用户导航体验。在实际开发中,可以根据应用需求结合 Tabs、SideBar 等组件构建更丰富的导航结构。
更多推荐
所有评论(0)