当前位置: 首页 > news >正文

《导航切换》案例

通过该案例,我们可以熟练掌握以下知识点
● 使用页Tabs组件进行页面导航
● Swiper组件实现轮播图、
● Grid网格布局
● 以及List列表布局
● 结构化数据封装
● 路由页面切换

1.页面效果

点击登录之后就会进入首页,效果如下图①所示。

iShot_2024-07-28_21.24

2.页面导航

为了开发方便,把图①效果简化为图②,先把页面导航做出来。

iShot_2024-07-28_21.41
完成上述导航效果,实际上由3个页面构成

● MainPage.ets 用于实现页面导航布局
● Home.ets 用于展示首页内容
● Setting.ets 用于展示我的页面内容

2.1MainPage

在pages目录下创建MainPage页面,使用Tabs组件进行页面导航,我们先把页面导航效果做出来。

点击查看代码
import { Home } from '../view/Home'
import { Setting } from '../view/Setting'@Entry
@Component
struct MainPage {@State currentIndex: number = 0@BuilderTabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) {Column() {Image(this.currentIndex === index ? selectedImg : normalImg).width(25).height(25)Text(title).margin({ top: 4 }).fontSize(10).fontColor(this.currentIndex === index ? '#1698CE' : '#6B6B6B')}.justifyContent(FlexAlign.Center).height(56).width('100%').onClick(() => {this.currentIndex = index;this.tabsController.changeIndex(this.currentIndex);})}private tabsController: TabsController = new TabsController();build() {Tabs({barPosition: BarPosition.End,controller: this.tabsController}) {TabContent() {Home()}.padding({ left: 12, right: 12 }).backgroundColor('#F1F3FS').tabBar(this.TabBuilder('首页', 0,$r('app.media.home_selected'), $r('app.media.home_normal')))TabContent() {Setting()}.padding({ left: 12, right: 12 }).backgroundColor('#F1F3FS').tabBar(this.TabBuilder('我的', 1,$r('app.media.mine_selected'), $r('app.media.mine_normal')))}.width('100%').backgroundColor(Color.White).barHeight(56).onChange((index: number) => {this.currentIndex = index;})}
}
## 2.3 Setting 在view目录下创建Setting.ets页面,代码如下
点击查看代码
@Component
export struct Setting {build() {Column() {Text('我的')}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
# 3.首页(Home.ets) 接下来,完成首页效果。

image
整体采用Colum布局完成,依次从上到下进行代码编写

点击查看代码
@Entry
@Component
export struct Home {build() {Column({ space: 12 }) {//Text头部标题//Swiper轮播图//Text文本//FristGrid网格//SecondGrid网格}}
}

3.1 头部标题

点击查看代码
Text('首页').fontSize(24).fontWeight(FontWeight.Medium).width('100%').margin({top:12})
## 3.2 Swiper轮播图 ### 3.2.1 准备轮播图数据 新建ets/viewmode/MainViewModel.ets。代码如下
点击查看代码
//导出MainViewModel类,以便其他位置使用
export class MainViewModel {getSwiperImages(): Array<Resource> {let swiperImages: Resource[] = [$r('app.media.fig1'),$r('app.media.fig2'),$r('app.media.fig3'),$r('app.media.fig4'),]return swiperImages;}getFirstGridData(): Array<FirstGridItemData> {let firstGridData: FirstGridItemData[] = [new FirstGridItemData('我的最爱', $r('app.media.love')),new FirstGridItemData('历史记录', $r('app.media.record')),new FirstGridItemData('消息', $r('app.media.message')),new FirstGridItemData('购物车', $r('app.media.shopping')),new FirstGridItemData('我的目标', $r('app.media.target')),new FirstGridItemData('圈子', $r('app.media.circle')),new FirstGridItemData('收藏', $r('app.media.favorite')),new FirstGridItemData('回收站', $r('app.media.recycle')),]return firstGridData;}
}//创建对象并导出
export default new MainViewModel();

3.2.2 加载数据到界面

点击查看代码
Swiper() {ForEach(MainViewModel.getSwiperImages(), (img: Resource) => {Image(img).borderRadius(16).width('100%')})
}
.margin({ top: 12 })
.autoPlay(true) //自动播放
## 3.3 Grid网格一 ### 3.3.1 准备数据 1. 新建ets/viewmode/ItemData.ets,用于封装各种数据模型,它有一个图片和标题组成。
点击查看代码
//第一个网格的Item数据模型
export class FirstGridItemData {title: string		//item标题img: Resource		//item图标constructor(title: string, img: Resource) {this.title = title;this.img = img;}
}
2. 在ets/viewmode/MainViewModel准备8个FirstGridItemData,并存储到一个数组中
点击查看代码
//导出MainViewModel类,以便其他位置使用
export class MainViewModel {//...getFirstGridData(): Array<FirstGridItemData> {let firstGridData: FirstGridItemData[] = [new FirstGridItemData('我的最爱', $r('app.media.love')),new FirstGridItemData('历史记录', $r('app.media.record')),new FirstGridItemData('消息', $r('app.media.message')),new FirstGridItemData('购物车', $r('app.media.shopping')),new FirstGridItemData('我的目标', $r('app.media.target')),new FirstGridItemData('圈子', $r('app.media.circle')),new FirstGridItemData('收藏', $r('app.media.favorite')),new FirstGridItemData('回收站', $r('app.media.recycle')),]return firstGridData;}
}//创建对象并导出
export default new MainViewModel();
### 3.3.2 加载数据到界面
点击查看代码
Grid() {ForEach(MainViewModel.getFirstGridData(), (item: FirstGridItemData) => {GridItem() {Column() {Image(item.img).width(24).height(24)Text(item.title).fontSize(12).margin({ top: 4 })}}})
}
.height(124)
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(18)
.rowsGap(12)
.backgroundColor(Color.White)
.borderRadius(24)
## 3.4 Grid网格二 ### 3.4.1 准备数据 1. 新建类class SecondGridItemData用来表示网格二的数据模
点击查看代码
//第二个网格的Item数据模型
export class SecondGridItemData{title:stringsecondTitle:stringimg: Resourceconstructor(title: string, secondTitle: string, img: Resource) {this.title = title;this.secondTitle = secondTitle;this.img = img;}
}
2. 创建4个SecondGridItemData对象,并存入数据中。
点击查看代码
getSecondGridData():Array<SecondGridItemData>{let secondGridItemData: SecondGridItemData[] = [new SecondGridItemData('排行榜','厦门站,我们不见不散',$r('app.media.top')),new SecondGridItemData('新品发布','厦门站,我们部件不散',$r('app.media.new')),new SecondGridItemData('打牌闪购','更多大牌',$r('app.media.brand')),new SecondGridItemData('发现好物','厦门站,我们不见不散',$r('app.media.found')),]return secondGridItemData
}
### 3.4.2 加载数据到界面
点击查看代码
//...Text(’列表‘)Grid() {ForEach(MainViewModel.getSecondGridData(), (item: SecondGridItemData) => {GridItem() {Column() {Text(item.title).fontSize(16).fontWeight(FontWeight.Medium)Text(item.secondTitle).fontSize(12).fontColor('#99182431').margin({ top: 4 })}}.padding({ top: 8, left: 8 }).align(Alignment.TopStart).backgroundImage(item.img).backgroundImageSize(ImageSize.Cover)		//背景图、居中填充.borderRadius(12).width('100%').height('100%')})
}
.width('100%')
.height(260)
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.margin({ bottom: 55 })
# 4. 我的(Setting) 接下来,完成我的页面。下面是效果图和布局分析图。

image (1)
如上图所示,整体采用Column布局,然后依次从上到下完成代码编写。

4.1 个人信息

点击查看代码
import { ListItemData } from '../viewmodel/ItemData'
import MainViewModel from '../viewmodel/MainViewModel'
import router from '@ohos.router'@Entry
@Component
export struct Setting {build() {Column() {//1. 头部标题Text('我的').fontSize(24).fontWeight(FontWeight.Medium).width('100%').margin({ top: 12 })//2. 个人信息Row() {Image($r('app.media.account')).width(45)Column() {Text('李先生').fontSize(18).fontWeight(FontWeight.Bold)Text('quarkn@forxmail.com')}.alignItems(HorizontalAlign.Start).margin({ left: 25 })}.justifyContent(FlexAlign.Start).width('100%').height(100).backgroundColor(Color.White).margin({ top: 20 }).padding({ left: 20 }).borderRadius(12)}.width('100%').height('100%')}
}
## 4.2 功能列表
点击查看代码
import { ListItemData } from '../viewmodel/ItemData'
import MainViewModel from '../viewmodel/MainViewModel'
import router from '@ohos.router'@Entry
@Component
export struct Setting {build() {Column() {//1. 头部标题...//2. 头部标题...//3. 列表List() {ForEach(MainViewModel.getListData(), (item: ListItemData) => {ListItem() {Row() {Image(item.img).width(25)Text(item.title).margin({ left: 10 })Blank()if(item.index===0){Toggle({ type: ToggleType.Switch, isOn: false })}else {Image($r('app.media.arrow')).width(20)}}.width('100%').height(50).backgroundColor(Color.White).padding({ left: 10, right: 10 })}})}.borderRadius(12).margin({top:15}).divider({strokeWidth:0.25,color:Color.Grey,startMargin:40,endMargin: 10})Blank()Button('退出登录').width('80%').backgroundColor('#dedede').margin({bottom:100}).fontColor(Color.Red).onClick(()=>{router.replaceUrl({ url: "pages/LoginPage" })})}.width('100%').height('100%')}
}
## 4.3 退出按钮 点击登录按钮时,调整到登录页。
点击查看代码
import { ListItemData } from '../viewmodel/ItemData'
import MainViewModel from '../viewmodel/MainViewModel'
import router from '@ohos.router'@Entry
@Component
export struct Setting {build() {Column() {//1. 头部标题...//2. 头部标题...//3. 列表...Blank()	//弹性空白Button('退出登录').width('80%').backgroundColor('#dedede').margin({bottom:100}).fontColor(Color.Red).onClick(()=>{router.replaceUrl({ url: "pages/LoginPage" })	//跳转到登录页})}.width('100%').height('100%')}
}
最终效果如下图所示

iShot_2024-07-29_02.40
鸿蒙学习地址

http://www.jsqmd.com/news/25752/

相关文章:

  • 技术探究:Air8000工业引擎赋能的WiFi AP文件管理系统实现剖析!
  • iOS 26 内存占用监控 多工具协同下的性能稳定性分析实战
  • 图像处理效率神器:光影魔术手 4.7.2,小白也能秒出专业效果
  • 2025年太原办理防爆3C认证服务商权威推荐榜单:内蒙古防爆3C认证/呼和浩特办理防爆CCC认证/辽宁申请防爆3C认证机构精选
  • 2025年250型压滤机滤布定制厂家权威推荐榜单:380型压滤机滤布/500型压滤机滤布/870型压滤机滤布源头厂家精选
  • 【IEEE出版|往届EI检索】第二届智能驾驶与智慧交通国际学术会议(IDST 2025)
  • 玖奇脑筋急转弯问答版小程序:趣味互动新选择
  • 忍痛割爱,Spring Boot 宣布移除 Undertow!!
  • Git 免密认证:Git Credential Helper
  • 类和对象-对象的特性project4
  • 人人聘招聘系统:多端协同的企业招聘解决方案
  • 喵喵估价回收系统:一站式闲置回收解决方案,赋能回收行业数字化升级
  • 向量数据库chroma
  • 云原生向量数据库Milvus知识大全,看完这篇就够了[基本概念、系统架构、主要组件、应用场景]
  • 测试数据准备难题?一个Dify工作流,让你告别“巧妇难为无米之炊”
  • 如何使用 vxe-table 展开行实现展开子表父子表格
  • ubuntu操作系统增加swap内存 - Ladisson
  • stash 的一些操作
  • Ubuntu Netplan
  • 2025年成品岗亭供货厂家权威推荐榜单:成品门卫亭/小区保安亭/执法岗亭源头厂家精选
  • 实时期货、黄金贵金属、外汇数据接口文档
  • python动态加载插件 - ling
  • 实用指南:C++设计模式_结构型模式_适配器模式Adapter
  • 2025年混凝土预制管桩设备定做厂家权威推荐榜单:PHC管桩生产设备/PHC管桩生产线/混凝土管桩生产设备源头厂家精选
  • 2025年微小流量质量流量计企业权威推荐榜单:差压质量流量计/液体质量流量计/数字式质量流量计源头厂家精选
  • 2025年阻燃pp管厂商权威推荐榜单:阻燃pp管厂商/塑料pp管/pp化工管源头厂家精选
  • ArkTS语言(六)
  • rbd元数据
  • 2025 年氧舱厂家最新推荐榜,聚焦企业技术创新、产品品质与市场口碑深度解析方圆组合式/减压/盾构气压/高原平衡/实验/软体氧舱公司推荐
  • 2025年进口气动塑料球阀定制厂家权威推荐榜单:进口气动超低温球阀/进口气动三片式球阀/进口气动衬氟球阀源头厂家精选