鸿蒙应用开发(ArkTS)—健康生活应用解读(三)

关于上一篇文章

鸿蒙应用开发(ArkTS)—健康生活应用解读(二)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_73005007/article/details/139776594?spm=1001.2014.3001.5501
本文章继解读(二),进行第二部分主页面的实现,包括首页和饮食记录部分,我将分两部分解读UI部分

 如果大家有什么建议或者问题的话都可以给我留言,24H之内我肯定回复

UI设计(一)

首页

使用tabs组件实现首页视图内容的切换,需要与tabbar和tabcontent一起使用

tabs组件的定义

Tabs()// barposition.end或者 barposition.start
{
  Tabcontent(){
    Text('内容1')}
    .tabBar('标题1”)
  Tabcontent(){
    Text('内容2')}
.tabBar('标照2')
}
.width('100%')
.height('100%')
//.vertical()

默认的tabBar位置在顶部,可以通过 barposition改变( barposition.end或者 barposition.start)

.vertical()可以控制Tabs的水平或者纵向,在纵向布局(false)中,end代表在右侧

关于自定义tabbar样式,可以使用@Builder进行构造

@Builder TabBuilder(title:string,image:ResourceStr,index:number){
  Column({space:4)){
    Image(image)
    Text(title)
  }
.justifycontent(FlexAlign.Center)
}

 此处的index为角标,在样式变化时使用

关于样式的变化,可以定义一个状态变量接收角标,然后进行改变

@State currentIndex: number=0

 添加onchange接收角标

.onChange(index=>this.currendIndex=index)

判断是否为当前图标,如果是则改变

@Builder TabBuilder(title:string,image:ResourceStr,index:number){
  Column({space:4)){
    Image(image).fillcolor(this.currentIndex===index?color.blue:color.gray)
    Text(title).fillcolor(this.currentIndex===index?color.blue:color.gray)
  }
.justifycontent(FlexAlign.Center)
}

使用代码如下

饮食记录部分

首页:

true

首页的布局从上到下依次是由搜索栏(search),卡片(datepicker和swiper)和食物列表(List)

在这部分中,使用了两个新的组件 

search:搜索框组件,适用于浏览器的搜索内容输入框等应用场景,参数如下,来自官方API文档

关于Badge:可以附加在单个组件上用于信息标记的容器组件。

参数名

参数类型

必填

默认值

参数描述

count

number

-

设置提醒消息数。

说明:

小于等于0时不显示信息标记。

position

BadgePosition

BadgePosition.RightTop

设置提示点显示位置。

maxCount

number

99

最大消息数,超过最大消息时仅显示maxCount+。

style

BadgeStyle

-

Badge组件可设置样式,支持设置文本颜色、尺寸、圆点颜色和尺寸。

Badge(value: {value: string, position?: BadgePosition, style: BadgeStyle})

根据字符串创建标记组件。

从API version 9开始,该接口支持在ArkTS卡片中使用。

参数名

参数类型

必填

默认值

参数描述

value

string

-

提示内容的文本字符串。

position

BadgePosition

BadgePosition.RightTop

设置提示点显示位置。

style

BadgeStyle

-

Badge组件可设置样式,支持设置文本颜色、尺寸、圆点颜色和尺寸。

从API version 9开始,该接口支持在ArkTS卡片中使用。

名称

描述

RightTop

圆点显示在右上角。

Right

圆点显示在右侧纵向居中。

Left

圆点显示在左侧纵向居中。

从API version 9开始,该接口支持在ArkTS卡片中使用。

名称

类型

必填

默认值

描述

color

ResourceColor

Color.White

文本颜色。

fontSize

number | string

10

文本大小。

单位:vp

说明:

不支持设置百分比。

badgeSize

number | string

16

Badge的大小。不支持百分比形式设置。当设置为非法值时,按照默认值处理。

单位:vp

badgeColor

ResourceColor

Color.Red

Badge的颜色。

代码实现 

index.ets

import { CommonConstants } from '../common/constants/CommonConstants'
@Entry
@Component
struct Index {
  @State currentIndex: number = 0
  selectColor(index: number) {
    return this.currentIndex === index ? $r('app.color.primary_color') : $r('app.color.gray')
  }

  @Builder TabBarBuilder(title: String , image: ResourceStr, index: number) {
    Column({ space: CommonConstants.SPACE_8 }) {
      Image(image)
        .width(22)
        .fillColor(this.selectColor(index))
      Text('title')
        .fontSize(14)
        .fillColor(this.selectColor(index))
    }
  }

  build() {
    Tabs({barPosition: BarPosition.End}){
      TabContent(){
        Text('饮食记录')
      }
      .tabBar(this.TabBarBuilder('首页',$r('app.media.P1'),0))
      TabContent(){
        Text('社区')
      }
      .tabBar(this.TabBarBuilder('社区',$r('app.media.P1'),1))
      TabContent(){
        Text('我的')
      }
      .tabBar(this.TabBarBuilder('我的',$r('app.media.P1'),2))

    }
    .width('100%')
    .height('100%')
    .onChange(index=>this.currentIndex=index)
  }
}

ItemList.ets

import { CommonConstants } from '../common/constants/CommonConstants'

@Component
struct ItemList {
  build() {
    Tabs() {
      TabContent() {

      }
      .tabBar('全部')
    }
    .width(CommonConstants.THOUSANDTH_900)
    .height('100%')
  }
}

CalorieStats.ets

import { CommonConstants } from '../../common/constants/CommonConstants'

@Component
export default  struct CalorieStats {
  @Prop intake: number
  @Prop expend: number
  recommend: number = CommonConstants.RECOMMEND_CALORIE

  remainCalorie() {
    return this.recommend - this.intake + this.expend
  }

  build() {
    Row({ space: CommonConstants.SPACE_6 }) {
      // 1.饮食摄入
      this.StatsBuilder({ label: '饮食摄入', value: this.intake })
      // 2.还可以吃
      Stack() {
        // 2.1.进度条
        Progress({
          value: this.intake,
          total: this.recommend,
          type: ProgressType.Ring
        })
          .width(120)
          .style({ strokeWidth: CommonConstants.DEFAULT_10 })
          .color($r('app.color.primary_color'))
        // 2.2.统计数据
        this.StatsBuilder({ label: '还可以吃', value: this.remainCalorie(), tips: `推荐${this.recommend}` })
      }
      // 3.运动消耗
      this.StatsBuilder({ label: '运动消耗', value: this.expend })
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({ top: 30, bottom: 35 })
  }

  @Builder StatsBuilder($$: {
    label: string,
    value: number,
    tips?: string
  }) {
    Column({ space: CommonConstants.SPACE_6 }) {
      Text($$.label)
        .fontColor($r('app.color.gray'))
        .fontWeight(CommonConstants.FONT_WEIGHT_600)
      Text($$.value.toFixed(0))
        .fontSize(20)
        .fontWeight(CommonConstants.FONT_WEIGHT_700)
      if ($$.tips) {
        Text($$.tips)
          .fontSize(12)
          .fontColor($r('app.color.light_gray'))
      }
    }
  }
}

DatePickDialog.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@CustomDialog
export default struct DatePickDialog {
  controller: CustomDialogController
  selectedDate: Date = new Date()
  build() {
    Column({space:CommonConstants.SPACE_12}){
      DatePicker({
        start: new Date('2020-01-01'),
        end: new Date(),
        selected: this.selectedDate
      })
        .onChange((value: DatePickerResult) => {
          this.selectedDate.setFullYear(value.year, value.month, value.day)
        })
      Row({space:CommonConstants.SPACE_12}){
        Button('取消')
          .width(120)
          .backgroundColor($r('app.color.light_gray'))
          .onClick(() => this.controller.close())
        Button('确定')
          .width(120)
          .backgroundColor($r('app.color.primary_color'))
          .onClick(() => {
            // 1.保存日期到全局存储
            AppStorage.SetOrCreate('selectedDate', this.selectedDate.getTime())
            // 2.关闭窗口
            this.controller.close()
          })
      }
    }
    .padding(CommonConstants.SPACE_12)
  }
}

RecordIndex.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NutrientStats {
  @Prop carbon: number
  @Prop protein: number
  @Prop fat: number

  recommendCarbon: number = CommonConstants.RECOMMEND_CARBON
  recommendProtein: number = CommonConstants.RECOMMEND_PROTEIN
  recommendFat: number = CommonConstants.RECOMMEND_FAT

  build() {
    Row({space: CommonConstants.SPACE_6}){
      this.StatsBuilder({
        label: '碳水化合物',
        value: this.carbon,
        recommend: this.recommendCarbon,
        color: $r('app.color.carbon_color')
      })
      this.StatsBuilder({
        label: '蛋白质',
        value: this.protein,
        recommend: this.recommendProtein,
        color: $r('app.color.protein_color')
      })
      this.StatsBuilder({
        label: '脂肪',
        value: this.fat,
        recommend: this.recommendFat,
        color: $r('app.color.fat_color')
      })
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({top: 30, bottom: 35})
  }

  @Builder StatsBuilder($$:{label: string, value: number, recommend: number, color: ResourceStr}){
    Column({space: CommonConstants.SPACE_6}){
      Stack(){
        Progress({
          value: $$.value,
          total: $$.recommend,
          type: ProgressType.Ring
        })
          .width(95)
          .style({strokeWidth: CommonConstants.DEFAULT_6})
          .color($$.color)
        Column({space: CommonConstants.SPACE_6}){
          Text('摄入推荐')
            .fontSize(12)
            .fontColor($r('app.color.gray'))
          Text(`${$$.value.toFixed(0)}/${$$.recommend.toFixed(0)}`)
            .fontSize(18)
            .fontWeight(CommonConstants.FONT_WEIGHT_600)
        }
      }
      Text(`${$$.label}(克)`)
        .fontSize(12)
        .fontColor($r('app.color.light_gray'))
    }
  }
}

 SearchHeader.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct SearchHeader {
  build() {
    Row({space: CommonConstants.SPACE_6}){
      Search({placeholder: '搜索饮食或运动信息'})
        .textFont({size: 18})
        .layoutWeight(1)
      Badge({count: 1, position: BadgePosition.RightTop, style: {fontSize: 12}}){
        Image($r('app.media.P1'))
          .width(24)
      }
    }
    .width(CommonConstants.THOUSANDTH_940)
  }
}

StatsCard.ets

// @ts-nocheck
import BreakpointType from '../../common/bean/BreanpointType'
import BreakpointConstants from '../../common/constants/BreakpointConstants'
import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import CalorieStats from './CalorieStats'
import DatePickDialog from './DatePickDialog'

@Component
export default struct StatsCard {

  @StorageProp('selectedDate') selectedDate: number = DateUtil.beginTimeOfDay(new Date())
  @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM

  controller: CustomDialogController = new CustomDialogController({
    builder: DatePickDialog({selectedDate: new Date(this.selectedDate)})
  })
  build() {
    Column(){
      // 1.日期信息
      Row(){
        Text(DateUtil.formatDate(this.selectedDate))
          .fontColor($r('app.color.secondary_color'))
        Image($r('app.media.P1'))
          .width(20)
          .fillColor($r('app.color.secondary_color'))
      }
      .padding(CommonConstants.SPACE_8)
      .onClick(() => this.controller.open())

      // 2.统计信息
      Swiper(){
        // 2.1.热量统计
        CalorieStats({intake: this.info.intake, expend: this.expend})
        // 2.2.营养素统计
        NutrientStats({carbon: this.info.carbon, protein: this.info.protein,fat: this.info.fat})
      }
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(CommonConstants.DEFAULT_18)
      .indicatorStyle({selectedColor: $r('app.color.primary_color')})
      .displayCount(new BreakpointType({
        sm: 1,
        md: 1,
        lg: 2
      }).getValue(this.currentBreakpoint))
    }
    .width(CommonConstants.THOUSANDTH_940)
    .backgroundColor($r('app.color.stats_title_bgc'))
    .borderRadius(CommonConstants.DEFAULT_18)
  }
}

  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值