img

一、场景介绍

设置向导是应用程序中常见的功能,用于引导用户完成初始设置或功能配置。本文将介绍如何使用StepperItem组件构建一个应用设置向导,帮助用户逐步完成应用的个性化配置。

二、功能实现

1. 页面结构设计

@Entry
@Component
struct SetupWizardExample {
  @State currentStep: number = 0
  @State settings: {
    theme: string,
    fontSize: number,
    notifications: boolean,
    privacy: {
      dataCollection: boolean,
      locationService: boolean
    },
    sync: {
      autoSync: boolean,
      syncInterval: number
    }
  } = {
    theme: 'light',
    fontSize: 16,
    notifications: true,
    privacy: {
      dataCollection: false,
      locationService: false
    },
    sync: {
      autoSync: true,
      syncInterval: 30
    }
  }

  build() {
    Column() {
      // 标题
      Text('应用设置向导')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 40 })

      // 步骤指示器
      Stepper() {
        StepperItem() {
          Text('主题设置')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }.status(this.currentStep > 0 ? ItemState.COMPLETED :
                this.currentStep === 0 ? ItemState.CURRENT : ItemState.WAITING)

        StepperItem() {
          Text('通知设置')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }.status(this.currentStep > 1 ? ItemState.COMPLETED :
                this.currentStep === 1 ? ItemState.CURRENT : ItemState.WAITING)

        StepperItem() {
          Text('隐私设置')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }.status(this.currentStep > 2 ? ItemState.COMPLETED :
                this.currentStep === 2 ? ItemState.CURRENT : ItemState.WAITING)

        StepperItem() {
          Text('同步设置')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
        }.status(this.currentStep === 3 ? ItemState.CURRENT : ItemState.WAITING)
      }.margin({ bottom: 40 })

      // 设置内容区域
      this.renderSettingContent()

      // 导航按钮
      Row() {
        if (this.currentStep > 0) {
          Button('上一步')
            .onClick(() => this.previousStep())
            .margin({ right: 20 })
        }
        Button(this.currentStep === 3 ? '完成' : '下一步')
          .onClick(() => this.nextStep())
      }.margin({ top: 40 })
    }.padding(20)
  }

  @Builder
  renderSettingContent() {
    Column() {
      if (this.currentStep === 0) {
        this.renderThemeSettings()
      } else if (this.currentStep === 1) {
        this.renderNotificationSettings()
      } else if (this.currentStep === 2) {
        this.renderPrivacySettings()
      } else {
        this.renderSyncSettings()
      }
    }.width('100%')
  }

  @Builder
  renderThemeSettings() {
    Column() {
      Text('主题设置')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      Column() {
        Row() {
          Text('主题模式')
            .fontSize(16)
          Column() {
            Radio({ value: 'light', group: 'theme' })
              .checked(this.settings.theme === 'light')
              .onChange((isChecked) => {
                if (isChecked) {
                  this.settings.theme = 'light'
                }
              })
            Text('浅色')
              .fontSize(14)
              .margin({ left: 8 })
          }.margin({ right: 20 })

          Column() {
            Radio({ value: 'dark', group: 'theme' })
              .checked(this.settings.theme === 'dark')
              .onChange((isChecked) => {
                if (isChecked) {
                  this.settings.theme = 'dark'
                }
              })
            Text('深色')
              .fontSize(14)
              .margin({ left: 8 })
          }
        }.width('100%')
        .margin({ top: 20 })

        Column() {
          Text('字体大小')
            .fontSize(16)
            .margin({ top: 30, bottom: 10 })
          Slider({
            value: this.settings.fontSize,
            min: 12,
            max: 24,
            step: 1
          })
            .onChange((value: number) => {
              this.settings.fontSize = value
            })
          Text(`${this.settings.fontSize}px`)
            .fontSize(14)
            .margin({ top: 8 })
        }.width('100%')
      }
      .padding(20)
      .backgroundColor('#F5F5F5')
      .borderRadius(8)
    }
  }

  @Builder
  renderNotificationSettings() {
    Column() {
      Text('通知设置')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      Column() {
        Row() {
          Text('启用通知')
            .fontSize(16)
          Toggle({ type: ToggleType.Switch, isOn: this.settings.notifications })
            .onChange((isOn: boolean) => {
              this.settings.notifications = isOn
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)

        Text('开启后可以接收应用的重要通知和更新提醒')
          .fontSize(14)
          .opacity(0.6)
          .margin({ top: 8 })
      }
      .padding(20)
      .backgroundColor('#F5F5F5')
      .borderRadius(8)
    }
  }

  @Builder
  renderPrivacySettings() {
    Column() {
      Text('隐私设置')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      Column() {
        Row() {
          Text('数据收集')
            .fontSize(16)
          Toggle({ type: ToggleType.Switch, isOn: this.settings.privacy.dataCollection })
            .onChange((isOn: boolean) => {
              this.settings.privacy.dataCollection = isOn
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)

        Text('允许收集使用数据以改善应用体验')
          .fontSize(14)
          .opacity(0.6)
          .margin({ top: 8 })

        Row() {
          Text('位置服务')
            .fontSize(16)
          Toggle({ type: ToggleType.Switch, isOn: this.settings.privacy.locationService })
            .onChange((isOn: boolean) => {
              this.settings.privacy.locationService = isOn
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .margin({ top: 20 })

        Text('允许使用位置信息以获取本地化服务')
          .fontSize(14)
          .opacity(0.6)
          .margin({ top: 8 })
      }
      .padding(20)
      .backgroundColor('#F5F5F5')
      .borderRadius(8)
    }
  }

  @Builder
  renderSyncSettings() {
    Column() {
      Text('同步设置')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      Column() {
        Row() {
          Text('自动同步')
            .fontSize(16)
          Toggle({ type: ToggleType.Switch, isOn: this.settings.sync.autoSync })
            .onChange((isOn: boolean) => {
              this.settings.sync.autoSync = isOn
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)

        if (this.settings.sync.autoSync) {
          Column() {
            Text('同步间隔(分钟)')
              .fontSize(16)
              .margin({ top: 20, bottom: 10 })
            Slider({
              value: this.settings.sync.syncInterval,
              min: 15,
              max: 120,
              step: 15
            })
              .onChange((value: number) => {
                this.settings.sync.syncInterval = value
              })
            Text(`${this.settings.sync.syncInterval}分钟`)
              .fontSize(14)
              .margin({ top: 8 })
          }.width('100%')
        }
      }
      .padding(20)
      .backgroundColor('#F5F5F5')
      .borderRadius(8)
    }
  }

  nextStep() {
    if (this.currentStep === 3) {
      this.saveSettings()
    } else {
      this.currentStep++
    }
  }

  previousStep() {
    if (this.currentStep > 0) {
      this.currentStep--
    }
  }

  saveSettings() {
    // 在实际应用中,这里会保存设置到存储
    AlertDialog.show({
      title: '设置完成',
      message: '您的设置已保存',
      confirm: {
        value: '确定',
        action: () => {
          // 可以在这里进行页面跳转或其他操作
        }
      }
    })
  }
}

三、实现要点

1. 状态管理

  • 使用@State装饰器管理设置数据和当前步骤
  • 实现了设置项的双向绑定
  • 根据设置状态动态显示相关选项

2. 界面布局

  • 采用分步骤的方式展示不同类别的设置
  • 使用Column和Row组件组织设置项
  • 添加了适当的间距和背景色

3. 交互设计

  • 实现了设置项的即时更新
  • 添加了直观的控件操作
  • 提供了清晰的导航按钮

四、总结

本文通过HarmonyOS的StepperItem组件实现了一个设置向导界面,引导用户逐步完成应用的个性化配置。通过状态管理、界面布局和交互设计,实现了设置项的动态显示、即时更新和流畅的导航操作,帮助用户高效地完成设置过程,提升了设置向导的用户体验。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐