导航转场,就是手机App里一个页面变到另一个页面的动画效果,让用户感觉更流畅。想要做好这个效果,推荐使用Navigation组件。它就像是一个“导航员”,能帮你轻松地管理页面之间的跳转。再搭配上NavDestination组件,就像是给每个页面都标了个“地址”,让“导航员”知道要跳到哪里。这样,你就能很方便地定义页面之间的跳转关系,还能加上酷炫的动画效果,让用户爱上你的App!总之,Navigation组件和NavDestination组件是做导航转场的好帮手。
第一步
使用Navigation组件,轻松建个导航主页,再搞个路由栈NavPathStack管理页面跳转。就像有个“页面地图”,点哪儿就去哪儿,页面切换顺滑自然。这样,App里的不同页面就能方便地来回跳了,用户体验也更好!
// PageOne.ets
@Entry
@Component
struct NavigationDemo {
// 提供一个导航路径栈,用于管理页面导航
@Provide('pathInfos') pathInfos: NavPathStack = new NavPathStack();
// 定义一个包含设置项的数组
private listArray: Array<string> = ['WLAN', 'Bluetooth', 'Personal Hotspot', 'Connect & Share'];
build() {
Column() { // 创建一个垂直布局容器
Navigation(this.pathInfos) { // 创建一个导航组件,并传入路径栈
TextInput({ placeholder: '输入关键字搜索' }) // 添加一个文本输入框,用于搜索功能
.width('90%') // 设置宽度为父容器的90%
.height(40) // 设置高度为40像素
.margin({ bottom: 10 }); // 设置底部边距为10像素
// 通过List定义导航的一级界面
List({ space: 12, initialIndex: 0 }) { // 创建一个列表组件,设置项间距为12像素,初始索引为0
ForEach(this.listArray, (item: string) => { // 遍历设置项数组,生成每个列表项
ListItem() { // 创建一个列表项组件
Row() { // 创建一个水平布局容器
Row() { // 创建一个嵌套的水平布局容器,用于显示首字母图标
Text(`${item.slice(0, 1)}`) // 显示设置项的首字母
.fontColor(Color.White) // 设置字体颜色为白色
.fontSize(14) // 设置字体大小为14像素
.fontWeight(FontWeight.Bold); // 设置字体加粗
}
.width(30) // 设置宽度为30像素
.height(30) // 设置高度为30像素
.backgroundColor('#a8a8a8') // 设置背景颜色为灰色
.margin({ right: 20 }) // 设置右边距为20像素
.borderRadius(20) // 设置圆角半径为20像素
.justifyContent(FlexAlign.Center); // 设置内容居中对齐
Column() { // 创建一个垂直布局容器,用于显示设置项名称
Text(item) // 显示完整的设置项名称
.fontSize(16) // 设置字体大小为16像素
.margin({ bottom: 5 }); // 设置底部边距为5像素
}
.alignItems(HorizontalAlign.Start); // 设置内容左对齐
Blank(); // 添加一个空白占位符
Row() // 创建一个水平布局容器,用于显示箭头图标
.width(12) // 设置宽度为12像素
.height(12) // 设置高度为12像素
.margin({ right: 15 }) // 设置右边距为15像素
.border({
width: { top: 2, right: 2 }, // 设置上边和右边的边框宽度为2像素
color: 0xcccccc // 设置边框颜色为浅灰色
})
.rotate({ angle: 45 }); // 设置旋转角度为45度(形成箭头效果)
}
.borderRadius(15) // 设置圆角半径为15像素
.shadow({ radius: 100, color: '#ededed' }) // 设置阴影效果
.width('90%') // 设置宽度为父容器的90%
.alignItems(VerticalAlign.Center) // 设置内容垂直居中对齐
.padding({ left: 15, top: 15, bottom: 15 }) // 设置内边距
.backgroundColor(Color.White); // 设置背景颜色为白色
}
.width('100%') // 设置列表项宽度为父容器的100%
.onClick(() => { // 添加点击事件处理程序
this.pathInfos.pushPathByName(`${item}`, '详情页面参数'); // 将指定的页面信息入栈,并传递参数
});
}, (item: string): string => item);
}
.listDirection(Axis.Vertical) // 设置列表方向为垂直
.edgeEffect(EdgeEffect.Spring) // 设置边缘效果为弹簧效果
.sticky(StickyStyle.Header) // 设置粘性头部样式
.chainAnimation(false) // 禁用链式动画
.width('100%'); // 设置列表宽度为父容器的100%
}
.width('100%') // 设置导航组件宽度为父容器的100%
.mode(NavigationMode.Auto) // 设置导航模式为自动
.title('设置'); // 设置导航栏标题为“设置”
}
.size({ width: '100%', height: '100%' }) // 设置Column组件的尺寸为父容器的100%
.backgroundColor(0xf4f4f5); // 设置背景颜色为浅灰色
}
}
{
"module": {
...
"routerMap": "$profile:router_map",//第二步
...
}
}
//以下参数是需要配置自己的文件参数
{
"routerMap": [
{
"name": "Page1", // 页面标识名称,用于路由识别
"pageSourceFile": "src/main/ets/pages/PageOne.ets", // 页面源文件路径,指定了页面的具体实现文件位置
"buildFunction":"PageOneBuilder", // 构建函数名称,用于构建该页面的实例
"data": {
"description": "this is pageOne" // 页面描述信息,可用于提供页面的简要说明或元数据
}
}
]
}
- 3第三步:在Android的某个子页面里,给某个按钮或组件加个点击功能。点它的时候,不是干别的事儿,而是要回到上一个页面,就像浏览器的后退按钮一样。这时,如果你自己搞了个叫NavPathStack的东西来管页面跳转(虽然通常Navigation组件已经帮我们做了),那就得在这个点击功能里调用NavPathStack的pop方法。这个方法会去掉栈顶的那个页面,就像是从一堆书里抽走最上面的一本,于是你就回到了之前的那个页面。简单来说,就是点按钮,用pop,回上一页。
// PageOne.ets
@Builder
export function MyCommonPageBuilder(name: string, param: string) {
// 创建一个通用页面构建器,用于实例化 MyCommonPage 组件
// 参数:
// - name: 页面名称
// - param: 传递给页面的参数
MyCommonPage({ name: name, value: param });
}
@Component
export struct MyCommonPage {
// 导航路径栈,用于管理页面导航
pathInfos: NavPathStack = new NavPathStack();
// 页面名称
name: String = '';
// 状态变量,用于存储传递给页面的参数
@State value: String = '';
build() {
NavDestination() { // 创建一个导航目的地组件
Column() { // 创建一个垂直布局容器
Text(`${this.name}设置页面`) // 显示页面标题
.width('100%') // 设置宽度为父容器的100%
.fontSize(20) // 设置字体大小为20像素
.fontColor(0x333333) // 设置字体颜色为深灰色
.textAlign(TextAlign.Center) // 设置文本居中对齐
.textShadow({
radius: 2, // 设置阴影半径为2像素
offsetX: 4, // 设置水平偏移量为4像素
offsetY: 4, // 设置垂直偏移量为4像素
color: 0x909399 // 设置阴影颜色为浅灰色
})
.padding({ top: 30 }); // 设置顶部内边距为30像素
Text(`${JSON.stringify(this.value)}`) // 显示传递给页面的参数
.width('100%') // 设置宽度为父容器的100%
.fontSize(18) // 设置字体大小为18像素
.fontColor(0x666666) // 设置字体颜色为中灰色
.textAlign(TextAlign.Center) // 设置文本居中对齐
.padding({ top: 45 }); // 设置顶部内边距为45像素
Button('返回') // 创建一个按钮,用于返回上一页
.width('50%') // 设置宽度为父容器的50%
.height(40) // 设置高度为40像素
.margin({ top: 50 }) // 设置顶部外边距为50像素
.onClick(() => {
// 弹出路由栈栈顶元素,返回到上一个页面
this.pathInfos.pop();
});
}
.size({ width: '100%', height: '100%' }); // 设置Column组件的尺寸为父容器的100%
}.title(`${this.name}`) // 设置导航栏标题为页面名称
.onReady((ctx: NavDestinationContext) => {
// 当页面加载完成时,从NavDestinationContext获取当前所在的页面栈
this.pathInfos = ctx.pathStack;
});
}
}
页面路由示例代码(其中还包含了一些别的内容,可以试试学习一下)
https://gitee.com/Yy2575663368/hongmeng-page-routing-demo.git