HarmonyOS 应用 · 寝室投票首页深度解析:ended 布尔位与双态投票按钮

项目编号:49-dorm-vote 技术栈:HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面:首页 HomeTab.ets(94 行) 系列导航:(一)首页 · (二)创建 · (三)投票 · (四)结果

49 首页首屏


一、Theme.ets:粉色主题与投票产品的色彩语义

export class C {
  static readonly bg: string = '#F2F5FB';
  static readonly card: string = '#FFFFFF';
  static readonly cardSoft: string = '#F4F6FB';
  static readonly stroke: string = '#EAEEF6';

  static readonly text: string = '#1C2333';
  static readonly textSub: string = '#5A6483';
  static readonly textDim: string = '#9AA3BC';

  static readonly primary: string = '#FF6B9D';
  static readonly primarySoft: string = '#FCE7EF';
  static readonly accent: string = '#FF9DBA';
  static readonly warn: string = '#FF9F1C';
  static readonly danger: string = '#FF5A6E';
  static readonly ok: string = '#2BB673';
}

寝室投票的主色是 #FF6B9D(樱花粉),与班级任务的 #6C5CE7(深紫)、班费管理的 #00A862(翡翠绿)形成区分。粉色传递"轻社交/生活化/友好"的色彩语义——寝室投票是生活场景(外卖/值日/空调/电影),粉色比紫色更亲切、比绿色更活泼。primarySoft(#FCE7EF)浅粉做图块背景。


二、Index.ets:Tabs 容器与四 Tab 布局

    Tabs({ barPosition: BarPosition.End, index: this.current }) {
      TabContent() { HomeTab() }.tabBar(this.bar('首页', '🗳️', 0))
      TabContent() { Func1Tab() }.tabBar(this.bar('创建', '➕', 1))
      TabContent() { Func2Tab() }.tabBar(this.bar('投票', '✅', 2))
      TabContent() { ProfileTab() }.tabBar(this.bar('结果', '📊', 3))
    }
    .barBackgroundColor('#FFFFFF')
    .barHeight(60 + this.safeBottom)
    .scrollable(false)
    .onChange((idx: number) => { this.current = idx; })
    .width('100%').height('100%').backgroundColor(C.bg)

四个 Tab:首页(🗳️)/创建(➕)/投票(✅)/结果(📊)。投票的完整生命周期:查看投票 → 创建投票 → 参与投票 → 查看结果。


三、Vote interface:ended 布尔位

interface Vote {
  id: number;
  emoji: string;
  title: string;
  options: number;
  voted: number;
  total: number;
  ended: boolean;
}

七个字段:id 是 key 锚点,emoji 是投票图标,title 是问题,options 是选项数,voted 是已投人数,total 是总人数,ended 是"是否已结束"的布尔位。ended 是首页的核心状态字段——驱动按钮的双态变化。

  private votes: Vote[] = [
    { id: 1, emoji: '🍜', title: '今晚点什么外卖?', options: 4, voted: 3, total: 4, ended: false },
    { id: 2, emoji: '🧹', title: '本周谁值日打扫', options: 4, voted: 4, total: 4, ended: true },
    { id: 3, emoji: '❄️', title: '空调温度调到几度', options: 3, voted: 2, total: 4, ended: false },
    { id: 4, emoji: '🎬', title: '周末一起看什么电影', options: 5, voted: 1, total: 4, ended: false }
  ];

四个投票覆盖寝室生活场景:外卖(3/4 进行中)、值日(4/4 已结束)、空调(2/4 进行中)、电影(1/4 进行中)。ended 交替 false/true,验证按钮双态的渲染正确性。值日投票 voted: 4 = total: 4 全员投完自动结束。


四、Banner:粉色渐变品牌头

  @Builder
  Banner() {
    Row({ space: 12 }) {
      Text('🗳️').fontSize(38)
      Column({ space: 4 }) {
        Text('民主寝室,一起决定').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
        Text('4 人寝室 · 3 个进行中投票').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
      }.alignItems(HorizontalAlign.Start).layoutWeight(1)
    }
    .width('100%').padding(18).borderRadius(D.rLg)
    .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
  }

38 号 🗳️ + 16 号加粗白色标语"民主寝室,一起决定" + 12 号半透明统计。linearGradient 135° 从 C.primary(#FF6B9D)到 C.accent(#FF9DBA),粉色渐变传递"轻社交"的氛围。"3 个进行中投票"实时统计 ended === false 的数量。


五、VoteList:ended 驱动的双态按钮

  @Builder
  VoteList() {
    Column({ space: 12 }) {
      ForEach(this.votes, (v: Vote) => {
        Row({ space: 12 }) {
          Row() { Text(v.emoji).fontSize(26) }
          .width(50).height(50).backgroundColor(C.primarySoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center)
          Column({ space: 4 }) {
            Text(v.title).fontSize(15).fontWeight(FontWeight.Medium).fontColor(C.text).maxLines(1)
              .textOverflow({ overflow: TextOverflow.Ellipsis })
            Text(v.options + ' 个选项 · ' + v.voted + '/' + v.total + ' 人已投').fontSize(12).fontColor(C.textDim)
          }.alignItems(HorizontalAlign.Start).layoutWeight(1)
          Text(v.ended ? '已结束' : '投票').fontSize(12)
            .fontColor(v.ended ? C.textDim : '#FFFFFF')
            .padding({ left: 14, right: 14, top: 7, bottom: 7 })
            .backgroundColor(v.ended ? C.cardSoft : C.primary).borderRadius(D.rSm)
            .onClick(() => { promptAction.showToast({ message: v.ended ? '查看结果' : '参与投票' }); })
        }
        .width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
      }, (v: Vote) => v.id.toString())
    }.width('100%')
  }

ended 驱动双态按钮——文案、字色、底色三路分支:

// 文案:已结束 vs 投票
Text(v.ended ? '已结束' : '投票')

// 字色:灰色 vs 白色
.fontColor(v.ended ? C.textDim : '#FFFFFF')

// 底色:浅灰 vs 粉色
.backgroundColor(v.ended ? C.cardSoft : C.primary)

ended === true 时按钮"已结束"灰字浅灰底(视觉弱化),点击弹"查看结果";ended === false 时按钮"投票"白字粉底(CTA 突出),点击弹"参与投票"——已结束的投票不可再投。

50×50 粉色图块:C.primarySoft 浅粉底 + 26 号 emoji,borderRadius(D.rSm) 小圆角。标题 maxLines(1) + Ellipsis 单行省略。副标题"4 个选项 · 3/4 人已投"把选项数与投票进度合并为一句。

49 首页完整列表

49 首页已结束 Toast

49 首页投票 Toast


六、可演进方向

方向现状改法收益
投票跳转Toast 占位跳转投票 Tab / 结果 Tab功能闭环
自动结束静态 endedvoted === total 或倒计时自动结束状态自动流转
进度条纯文字 3/4卡片内嵌 voted/total 进度条投票进度可视化
数据源静态 4 条服务端拉取 + 实时刷新多人同步投票
分类筛选无进行中/已结束分段筛选快速定位

首页是寝室投票的概览——Banner 的粉色渐变 + VoteList 的 ended 驱动双态按钮。从条件渲染的状态按钮到 maxLines 的溢出处理,每一层都有明确的职责边界。

系列导航:(一)首页 · (二)创建 · (三)投票 · (四)结果

Logo

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

更多推荐