1669 字
8 分钟
HarmonyHealth 开发记录(二):欢迎页面实现
2025-03-29
无标签

欢迎界面1

欢迎界面2

模块概述

基于前两篇的基础知识和项目架构,我们开始实现 HarmonyHealth 的第一个重要页面 - 欢迎页面。该页面是用户首次打开应用时看到的界面,通过轮播图展示应用的主要功能和特点。通过本文,您将学习:

  • 轮播图的实现方法
  • 隐私协议的处理方式
  • 页面交互的设计原则
  • 用户体验的优化技巧

技术实现#

1. 页面结构#

核心组件

欢迎页面主要包含以下组件,每个组件都有其特定的功能和实现方式:

  • 轮播图展示区:展示应用特点
  • 底部操作按钮:提供用户交互
  • 隐私协议对话框:处理用户授权
import router from "@ohos.router";
import { UserPrivacyDialog } from "../dialog/UserPrivacyDialog";

// 欢迎页数据接口
interface WelcomeItem {
  title: string;
  description: string;
  image: Resource;
}

@Entry
@Component
struct WelcomeIndex {
  @State currentIndex: number = 0;
  @State showPrivacyDialog: boolean = false;
  private swiperController: SwiperController = new SwiperController();
  private dialogController: CustomDialogController;

  // 欢迎页数据
  private welcomeData: WelcomeItem[] = [
    {
      title: "智能健康助手",
      description: "基于人工智能的健康管理专家",
      image: $r("app.media.icon")
    },
    {
      title: "个性化健康计划",
      description: "根据您的身体状况定制专属健康方案",
      image: $r("app.media.icon")
    },
    {
      title: "全面健康数据",
      description: "记录并分析您的健康数据,提供专业建议",
      image: $r("app.media.icon")
    }
  ];

  aboutToAppear() {
    // 初始化隐私协议对话框
    this.dialogController = new CustomDialogController({
      builder: UserPrivacyDialog({
        controller: this.dialogController,
        confirm: () => {
          router.pushUrl({ url: "pages/LoginPage" });
        },
        cancel: () => {
          this.showPrivacyDialog = false;
          this.dialogController.close();
        }
      }),
      cancel: () => {
        this.showPrivacyDialog = false;
      },
      autoCancel: true
    });
  }

  build() {
    Column() {
      Stack({ alignContent: Alignment.Bottom }) {
        // 轮播图
        Swiper(this.swiperController) {
          ForEach(this.welcomeData, (item: WelcomeItem, index: number) => {
            Column() {
              Image(item.image)
                .width("80%")
                .height("50%")
                .objectFit(ImageFit.Contain)
                .margin({ top: 60 })
              
              Text(item.title)
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .margin({ top: 40 })
              
              Text(item.description)
                .fontSize(16)
                .fontColor("#666666")
                .margin({ top: 10 })
                .textAlign(TextAlign.Center)
                .padding({ left: 20, right: 20 })
            }
            .width("100%")
            .height("100%")
            .justifyContent(FlexAlign.Start)
            .alignItems(HorizontalAlign.Center)
          })
        }
        .index(this.currentIndex)
        .autoPlay(false)
        .indicator(true)
        .loop(false)
        .onChange((index: number) => {
          this.currentIndex = index;
        })
        .width("100%")
        .height("100%")
        
        // 底部按钮区域
        Column() {
          if (this.currentIndex === this.welcomeData.length - 1) {
            Button("开始使用")
              .width("80%")
              .height(50)
              .backgroundColor("#007DFF")
              .borderRadius(25)
              .fontSize(18)
              .fontColor(Color.White)
              .onClick(() => {
                this.showPrivacyDialog = true;
                this.dialogController.open();
              })
          } else {
            Button("下一步")
              .width("80%")
              .height(50)
              .backgroundColor("#007DFF")
              .borderRadius(25)
              .fontSize(18)
              .fontColor(Color.White)
              .onClick(() => {
                this.currentIndex++;
                this.swiperController.showNext();
              })
          }

          Text("跳过")
            .fontSize(16)
            .fontColor("#666666")
            .margin({ top: 15, bottom: 40 })
            .onClick(() => {
              this.currentIndex = this.welcomeData.length - 1;
              this.swiperController.showNext();
            })
        }
        .width("100%")
        .alignItems(HorizontalAlign.Center)
      }
      .width("100%")
      .height("100%")
    }
    .width("100%")
    .height("100%")
  }
}
代码说明
  • 使用 @State 管理页面状态
  • 通过 SwiperController 控制轮播行为
  • 使用 CustomDialogController 管理对话框
  • 实现页面跳转和状态更新

2. 隐私协议对话框#

隐私处理

隐私协议对话框是欢迎页面的重要组成部分,确保用户在使用应用前了解并同意相关条款。实现时需要注意:

  • 协议内容的完整性
  • 用户选择的处理
  • 界面交互的友好性
@Component
export struct UserPrivacyDialog {
  @Prop controller: CustomDialogController;
  @Prop confirm: () => void;
  @Prop cancel: () => void;

  build() {
    Column() {
      Text("用户隐私协议")
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 20 })

      Scroll() {
        Text("在此处显示完整的隐私协议内容...")
          .fontSize(16)
          .padding(20)
      }
      .width("100%")
      .height("60%")

      Row() {
        Button("不同意")
          .width("40%")
          .height(40)
          .backgroundColor("#F5F5F5")
          .fontColor("#666666")
          .onClick(() => {
            this.cancel();
          })

        Button("同意")
          .width("40%")
          .height(40)
          .backgroundColor("#007DFF")
          .fontColor(Color.White)
          .onClick(() => {
            this.confirm();
          })
      }
      .width("100%")
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ top: 20, bottom: 20 })
    }
    .width("90%")
    .height("80%")
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}
对话框实现要点
  • 使用 Scroll 组件支持长文本滚动
  • 提供明确的同意/不同意选项
  • 实现对话框的显示和隐藏控制
  • 处理用户交互事件

用户体验优化#

交互设计
  1. 页面交互优化

    • 实现平滑的轮播切换效果
    • 添加页面指示器
    • 支持手势滑动切换
    • 提供跳过功能
  2. 视觉设计优化

    • 使用清晰的图标和文字
    • 保持一致的视觉风格
    • 优化按钮布局和样式
    • 添加适当的动画效果
优化细节
  • 轮播图切换添加过渡动画
  • 按钮点击添加反馈效果
  • 文字大小和颜色要符合规范
  • 布局要适应不同屏幕尺寸

隐私协议处理#

隐私保护
  1. 协议展示

    • 使用对话框展示完整协议
    • 支持协议内容滚动查看
    • 提供明确的同意/不同意选项
    • 确保协议内容完整显示
  2. 用户选择处理

    • 记录用户选择结果
    • 根据选择进行相应跳转
    • 处理取消操作
    • 保存用户授权状态

学习要点#

技术收获
  1. 轮播图实现

    • 使用 Swiper 组件实现轮播效果
    • 掌握 SwiperController 控制轮播行为
    • 理解 ForEach 循环渲染列表数据
    • 实现自定义轮播指示器
  2. 对话框实现

    • 使用 CustomDialogController 控制对话框
    • 实现对话框的显示和隐藏
    • 处理用户交互事件
    • 优化对话框动画效果

学习总结#

关键收获
  1. 轮播图实现

    • 轮播图是展示应用特点的有效方式
    • 控制器可以精确控制轮播行为
    • 指示器提供良好的用户体验
    • 动画效果提升交互体验
  2. 对话框设计

    • 对话框需要清晰的交互逻辑
    • 事件处理要考虑用户选择
    • 动画效果提升用户体验
    • 内容展示要完整清晰
  3. 状态管理

    • 状态变量要合理设计
    • 状态更新要触发UI刷新
    • 状态变化要考虑性能影响
    • 状态持久化要安全可靠
  4. 页面导航

    • 路由跳转要符合用户预期
    • 参数传递要确保类型安全
    • 返回操作要处理用户数据
    • 页面切换要流畅自然

下一步学习计划#

学习路线
  1. 优化轮播图动画效果

    • 实现自定义切换动画
    • 优化指示器样式
    • 添加手势交互
    • 提升性能表现
  2. 完善对话框交互体验

    • 优化动画效果
    • 改进交互方式
    • 提升可访问性
    • 适配不同设备
  3. 学习更多状态管理方式

    • 探索状态管理库
    • 实现状态持久化
    • 优化状态更新
    • 提升性能表现
  4. 实践复杂页面跳转场景

    • 实现页面间通信
    • 处理页面状态
    • 优化跳转动画
    • 提升用户体验
注意事项
  1. 性能优化

    • 避免不必要的重渲染
    • 优化图片加载
    • 减少内存占用
    • 提升响应速度
  2. 用户体验

    • 保持界面响应流畅
    • 提供适当的反馈
    • 考虑不同设备适配
    • 确保可访问性
NOTE

本文是 HarmonyHealth 系列开发记录的第三篇,基于前两篇的基础,我们实现了应用的第一个重要页面。后续文章将逐步实现更多功能模块。建议读者在开发过程中注意用户体验和性能优化。