news 2026/7/17 0:36:10

鸿蒙原生开发手记:徒步迹 - 首页布局设计与Scroll滚动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙原生开发手记:徒步迹 - 首页布局设计与Scroll滚动

鸿蒙原生开发手记:徒步迹 - 首页布局设计与Scroll滚动

使用 Scroll 和 ForEach 构建可滚动的首页


一、前言

首页是 App 的门面,需要展示丰富的信息同时保持良好的浏览体验。徒步迹的首页包括:今日概览、快捷功能入口、推荐路线三大模块。

本文详解使用 Scroll 组件构建可滚动布局。


二、首页布局架构

Scroll(可滚动容器) └── Column(垂直排列) ├── 用户问候语 ├── 今日概览卡片 │ ├── 步数 │ ├── 距离 │ └── 卡路里 ├── 快捷功能 │ ├── 开始徒步 │ ├── 路线推荐 │ ├── 拍照记录 │ └── 我的团队 └── 推荐路线列表 ├── 路线卡片 1 ├── 路线卡片 2 └── 路线卡片 3

三、核心代码

@Entry @Component struct HomePage { @State userName: string = '徒步爱好者'; @State todaySteps: string = '8,642'; @State todayDistance: string = '5.2'; @State todayCalories: string = '320'; build() { Column() { // 顶部问候区(固定,不滚动) Row() { Column() { Text(`你好, ${this.userName}`) .fontSize(18) .fontWeight(FontWeight.Bold); Text('今天是个徒步的好天气') .fontSize(13) .fontColor('#666'); } .alignItems(HorizontalAlign.Start) .layoutWeight(1); // 用户头像 Image($r('app.media.app_icon')) .width(40).height(40) .borderRadius(20); } .width('100%') .padding({ left: 20, right: 20, top: 12 }); // 可滚动内容区 Scroll() { Column() { // 今日概览卡片 this.TodayOverviewCard(); // 快捷功能 this.QuickActionsSection(); // 推荐路线 this.RecommendedRoutesSection(); } .width('100%') .padding({ bottom: 80 }); } .layoutWeight(1); } .width('100%') .height('100%') .backgroundColor('#F5F5F5'); }

四、Scroll 组件详解

4.1 常用属性

Scroll() { // 内容区域 Column() { /*...*/ } } .scrollable(ScrollDirection.Vertical) // 滚动方向 .edgeEffect(EdgeEffect.Spring) // 边缘弹性效果 .scrollBar(BarState.Auto) // 滚动条显示方式 .enableScrollInteraction(true) // 是否允许滚动

4.2 滚动控制

// 创建 Scroll 控制器 private scroller: Scroller = new Scroller(); Scroll(this.scroller) { // ... } .onScroll((x: number, y: number) => { console.log(`滚动位置: ${x}, ${y}`); }); // 编程式滚动 this.scroller.scrollTo({ xOffset: 0, yOffset: 200, // 滚动到指定位置 duration: 300, // 动画时长 }); this.scroller.scrollEdge(Edge.Top); // 滚到顶部 this.scroller.scrollPage(true); // 翻页

五、卡片组件设计

5.1 今日概览卡片

@Builder TodayOverviewCard() { Column() { Text('今日概览') .fontSize(16) .fontWeight(FontWeight.Medium) .width('100%'); Row() { StatItem('🏃', this.todaySteps, '步', '步'); StatItem('📏', this.todayDistance, '距离', 'km'); StatItem('🔥', this.todayCalories, '卡路里', 'kcal'); } .width('100%') .margin({ top: 16 }) .justifyContent(FlexAlign.SpaceAround); } .padding(16) .backgroundColor(Color.White) .borderRadius(16) .margin({ left: 20, right: 20, top: 16 }); } @Builder StatItem(icon: string, value: string, label: string, unit: string) { Column() { Text(icon).fontSize(28); Text(value).fontSize(22).fontWeight(FontWeight.Bold).margin({ top: 4 }); Row() { Text(label).fontSize(12).fontColor('#999'); Text(unit).fontSize(12).fontColor('#999').margin({ left: 2 }); } .margin({ top: 2 }); } .alignItems(HorizontalAlign.Center); }

六、总结

首页是一个 App 最复杂的页面之一,需要考虑信息架构、布局层次和滚动性能。使用 Scroll + Column 的组合是最常见的 ArkUI 布局模式,结合 @Builder 拆分组装,让代码清晰可维护。

下一篇文章将集成鸿蒙 MapKit 地图组件,实现路线地图展示。


下一篇预告:鸿蒙原生开发手记:徒步迹 - MapKit 地图组件集成

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 0:31:58

Agent Loop:一个循环统治所有 Agent

所有 AI Agent 框架的核心都是一个循环。Claude Agent SDK 把 Claude Code 内部那个循环完整开放出来了——理解它,你就理解了 Agent 的心脏。 这是 Claude Agent SDK 深度实践系列的第一篇。我们从最核心的概念切入:Agent Loop。 如果你用过 Claude Co…

作者头像 李华
网站建设 2026/7/17 0:29:33

爬虫转大模型:从上线前检查开始讲

聊《大模型岗位变了,爬虫工程师该补的还是算法吗?》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要先把这篇文章的目标说清楚:看完之后,你应该能判断这件事值不值…

作者头像 李华
网站建设 2026/7/17 0:28:25

Android随笔-startServicebindService

一、核心区别对比 特性startService()bindService()启动方式直接启动,无需组件绑定需要与组件(Activity/Fragment)绑定生命周期onCreate() → onStartCommand()onCreate() → onBind()与调用者关系调用者与 Service 无直接关联调用者与 Serv…

作者头像 李华
网站建设 2026/7/17 0:18:55

CodeBuddy中配置Redis MCP 连接与排错实战

CodeBuddy中配置Redis MCP 连接与排错实战 从零配置 Redis MCP Server&#xff0c;到踩遍所有坑最终打通&#xff0c;列出数据库全部 key 的完整实录。适用于 Redis < 6.0 的本地环境。 一、背景与目标 在 CodeBuddy&#xff08;或其它支持 MCP 协议的客户端&#xff09;中…

作者头像 李华