当前位置: 代码网 > it编程>App开发>Android > 实现数据持久化和页面交互

实现数据持久化和页面交互

2024年08月02日 Android 我要评论
好的如果你看到本篇文章你就可以开心一下了,因为这是此次实战项目开发的最后一篇文章了(完结撒花)我会在这篇文章的最下方附上我的鸿蒙开发文件和实验报告,有需要的同学可以参考那么本篇文章要继续完成饮食记录页面的交互部分并完成最终的数据持久化保存。

好的如果你看到本篇文章你就可以开心一下了,因为这是此次实战项目开发的最后一篇文章了(完结撒花)

我会在这篇文章的最上方附上我的鸿蒙开发文件和实验报告,有需要的同学可以参考

那么本篇文章要继续完成饮食记录页面的交互部分并完成最终的数据持久化保存

正式开发

回到开发工具我们先找到饮食记录的页面,并进行修改

@component
export default struct recordindex {

  @storageprop('selecteddate')
  @watch('abouttoappear')
  selecteddate: number = dateutil.begintimeofday(new date())

  @provide records: recordvo[] = []

  @prop @watch('handlepageshow') ispageshow: boolean

  handlepageshow(){
    if(this.ispageshow){
      this.abouttoappear()
    }
  }

  async abouttoappear(){
    this.records = await recordservice.queryrecordbydate(this.selecteddate)
  }

  build() {
    column(){
      // 1.头部搜索栏
      searchheader()
      // 2.统计卡片
      statscard()
      // 3.记录列表
      recordlist()
        .layoutweight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundcolor($r('app.color.index_page_background'))
  }
}

并且对statscard、calorstats、recordlist的参数等进行修改

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 recordservice from '../../service/recordservice'
import recordvo from '../../viewmodel/recordvo'
import statsinfo from '../../viewmodel/statsinfo'
import caloriestats from './caloriestats'
import datepickdialog from './datepickdialog'
import nutrientstats from './nutrientstats'

@component
export default struct statscard {

  @storageprop('selecteddate') selecteddate: number = dateutil.begintimeofday(new date())
  @storageprop('currentbreakpoint') currentbreakpoint: string = breakpointconstants.breakpoint_sm

  @consume @watch('handlerecordschange') records: recordvo[]
  @state info: statsinfo = new statsinfo()

  handlerecordschange(){
    this.info = recordservice.calculatestatsinfo(this.records)
  }

  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.ic_public_spinner'))
          .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.info.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)
  }
}
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'))
      }
    }
  }
}
@extend(text) function graytext(){
  .fontsize(14)
  .fontcolor($r('app.color.light_gray'))
}

@component
export default struct recordlist {

  @consume @watch('handlerecordschange') records: recordvo[]
  @state groups: groupinfo<recordtype, recordvo>[] = []

  handlerecordschange(){
    this.groups = recordservice.calculategroupinfo(this.records)
  }


  build() {
    list({space: commonconstants.space_10}){
      foreach(this.groups, (group: groupinfo<recordtype, recordvo>) => {
        listitem(){
          column({space: commonconstants.space_8}){
            // 1.分组的标题
            row({space: commonconstants.space_4}){
              image(group.type.icon).width(24)
              text(group.type.name).fontsize(18).fontweight(commonconstants.font_weight_700)
              text(`建议${group.type.min}~${group.type.max}千卡`).graytext()
              blank()//空白
              text(group.calorie.tofixed(0)).fontsize(14).fontcolor($r('app.color.primary_color'))
              text('千卡').graytext()
              image($r('app.media.ic_public_add_norm_filled'))
                .width(20)
                .fillcolor($r('app.color.primary_color'))
            }
            .width('100%')
            .onclick(() => {
              router.pushurl({
                url: 'pages/itemindex',
                params: {type: group.type}
              })
            })
            // 2.组内记录列表
            list(){
              foreach(group.items, (item: recordvo) => {
                listitem(){
                  row({space: commonconstants.space_6}){
                    image(item.recorditem.image).width(50)
                    column({space: commonconstants.space_4}){
                      text(item.recorditem.name).fontweight(commonconstants.font_weight_500)
                      text(`${item.amount}${item.recorditem.unit}`).graytext()
                    }
                    blank()
                    text(`${item.calorie.tofixed(0)}千卡`).graytext()
                  }
                  .width('100%')
                  .padding(commonconstants.space_6)
                }.swipeaction({end: this.deletebutton.bind(this)})
              })
            }
            .width('100%')
          }
          .width('100%')
          .backgroundcolor(color.white)
          .borderradius(commonconstants.default_18)
          .padding(commonconstants.space_12)
        }
      })
    }
    .width(commonconstants.thousandth_940)
    .height('100%')
    .margin({top: 10})
  }

  @builder deletebutton(){
    image($r('app.media.ic_public_delete_filled'))
      .width(20)
      .fillcolor(color.red)
      .margin(5)
  }
}

完成跳转部分后进入itemindex

同样进行修改 

@extend(button) function panelbuttonstyle(){
  .width(120)
  .type(buttontype.normal)
  .borderradius(6)
}

@entry
@component
struct itemindex {
  @state amount: number = 1
  @state value: string = ''
  @state showpanel: boolean = false
  @state item: recorditem = null
  @state type: recordtype = recordtypes[0]
  @state isfood: boolean = true

  onpanelshow(item: recorditem) {
    this.amount = 1
    this.value = ''
    this.item = item
    this.showpanel = true
  }

  onpageshow(){
    // 1.获取跳转时的参数
    let params: any = router.getparams()
    // 2.获取点击的饮食记录类型
    this.type = params.type
    this.isfood = this.type.id !== recordtypeenum.workout
  }

  build() {
    column() {
      // 1.头部导航
      this.header()
      // 2.列表
      itemlist({ showpanel: this.onpanelshow.bind(this), isfood: this.isfood })
        .layoutweight(1)
      // 3.底部面板
      panel(this.showpanel) {
        // 3.1.顶部日期
        itempanelheader()
        // 3.2.记录项卡片
        if(this.item){
          itemcard({amount: this.amount, item: $item})
        }
        // 3.3.数字键盘
        numberkeyboard({amount: $amount, value: $value})
        // 3.4.按钮
        this.panelbutton()
      }
      .mode(panelmode.full)//全部显示
      .dragbar(false)//不可调整高度
      .backgroundmask($r('app.color.light_gray'))//蒙版颜色浅灰
      .backgroundcolor(color.white)//背景颜色
    }
    .width('100%')
    .height('100%')
  }

  @builder panelbutton(){
    row({space: commonconstants.space_6}){
      button('取消')
        .panelbuttonstyle()
        .backgroundcolor($r('app.color.light_gray'))
        .onclick(() => this.showpanel = false)
      button('提交')
        .panelbuttonstyle()
        .backgroundcolor($r('app.color.primary_color'))
        .onclick(() => {
          // 1.持久化保存
          recordservice.insert(this.type.id, this.item.id, this.amount)
            .then(() => {
              // 2.关闭弹窗
              this.showpanel = false
            })
        })
    }
    .margin({top: 10})
  }

  @builder header() {
    row() {
      image($r('app.media.ic_public_back'))
        .width(24)
        .onclick(() => router.back())
      blank()
      text(this.type.name).fontsize(18).fontweight(commonconstants.font_weight_600)
    }
    .width(commonconstants.thousandth_940)
    .height(32)
  }
}

修改饮食列表页

@component
export default struct itemlist {
  showpanel: (item: recorditem) => void
  @prop isfood: boolean

  build() {
    tabs() {
      tabcontent() {
        this.tabcontentbuilder(itemmodel.list(this.isfood))
      }
      .tabbar('全部')

      foreach(
        itemmodel.listitemgroupbycategory(this.isfood),
        (group: groupinfo<itemcategory, recorditem>) => {
          tabcontent() {
            this.tabcontentbuilder(group.items)
          }
          .tabbar(group.type.name)
        })
    }
    .width(commonconstants.thousandth_940)
    .height('100%')
    .barmode(barmode.scrollable)
  }

  @builder tabcontentbuilder(items: recorditem[]) {
    list({ space: commonconstants.space_10 }) {
      foreach(items, (item: recorditem) => {
        listitem() {
          row({ space: commonconstants.space_6 }) {
            image(item.image).width(50)
            column({ space: commonconstants.space_4 }) {
              text(item.name).fontweight(commonconstants.font_weight_500)
              text(`${item.calorie}千卡/${item.unit}`).fontsize(14).fontcolor($r('app.color.light_gray'))
            }.alignitems(horizontalalign.start)

            blank()
            image($r('app.media.ic_public_add_norm_filled'))
              .width(18)
              .fillcolor($r('app.color.primary_color'))
          }
          .width('100%')
          .padding(commonconstants.space_6)
        }
        .onclick(() => this.showpanel(item))
      })
    }
    .width('100%')
    .height('100%')
  }
}

营养素统计同样修改

@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'))
    }
  }
}

最终测试

经过我们的测试,实战项目开发的数据持久化和页面交互功能同预期一样正常使用

小结

那么本项目到此就算彻底结束了,我在这里也附上我的全部代码

ok,我们这里附上黑马程序员实现数据持久化和页面交互的视频链接,文章配合视频更好理解哦。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com