#打卡不停更#【木棉花】:基于ArkUI的运动记录Demo 原创

木棉花潘颖琳
发布于 2022-10-15 17:32
浏览
1收藏

前言

在参加了"HarmonyOS ArkUI入门训练营——健康生活实战"后,了解并学习了声明式UI开发框架及组件用法,本文是对笔者结营作品中作一个小分享。在笔者上篇及前篇文章中,已对本demo作了部分组件的介绍,本文将对剩余部分作介绍分享~

概述

本文主要介绍的是搜索栏跳转至搜索结果界面,以及前述文章介绍的组件的应用。效果图如下:
#打卡不停更#【木棉花】:基于ArkUI的运动记录Demo-鸿蒙开发者社区

正文

一、工程文件架构

#打卡不停更#【木棉花】:基于ArkUI的运动记录Demo-鸿蒙开发者社区

二、完善主界面及数据的传递

1、数据传递实现运动记录的增删改查

由于运动记录的增删改查是在弹窗组件的点击事件里相应的,起初我是打算使用@Link来传递数据的,但是在自定义弹窗组件的builder里会对$修饰的变量报错,于是我就改用全局变量了。为了响应变量的状态变化,用@State装饰。也许用数据库会更方便些,后期再作优化吧~

var RDArray: Array<RecordData> = []
var RSports: Array<SportsData> = []

Record 弹窗下定义变量

  @State RecordDataArray: Array<RecordData> = RDArray
  @State RecordSports: Array<SportsData> = RSports

在上上篇文章提到的弹窗组件中,定义点击事件。“修改记录”模式下,“删除记录”按键的“确定”响应代码如下:

secondaryButton: {
                            value: '确定',
                            action: () => {
                              RDArray.splice(this.item_index, 1)
                              RSports.splice(this.item_index, 1)
                              this.controller.close()
                            }

主弹窗右上角的“确定”按键响应代码如下:

 if (this.mode == 0) {
                RDArray.push({
                  'name': this.sportsItem.name,
                  'image': this.sportsItem.image,
                  'time': this.time,
                  'sum': this.sum
                })
                RSports.push(this.sportsItem)
              }
              else if (this.mode == 1) {
                RDArray[this.item_index]=
              {
                  'name': this.sportsItem.name,
                  'image': this.sportsItem.image,
                  'time': this.time,
                  'sum': this.sum
                }
                RSports.push(this.sportsItem)
              }

2、完善主页面

主页面底部是有两个页签的导航栏,第一个页签显示目录界面,该界面的顶部有一个搜索栏,与下方的目录成纵向布局,第二个页签显示记录界面。记录界面的组件与上篇文章提到的List组件用法无异,只是渲染的数据不同罢了,代码相似所以本文就不介绍了。此外对于记录界面,若无记录则显示“暂无记录”,为了让界面美观些,笔者给背景添加了图片。点击“搜索”按键时会带参跳转至搜索结果的页面’pages/search_result’,代码如下:

@Entry
@Component
struct SportsCategoryList {
  @State RDArray: Array<RecordData> = RDArray
  @State RSports: Array<SportsData> = RSports
  @State currentIndex: number = 0;
  @State search_item: string = '运动名称';
  private sportsItem: SportsData[] = initializeOnStartup()

  @Builder bottomBarBuilder(name: string, image_active: Resource, image_inactive: Resource, index: number) {
    Column() {
      Image(this.currentIndex === index ? image_active : image_inactive).width(32).aspectRatio(1).fillColor(this.currentIndex === index ? '#3ECF69' : '#bfbfbf')
      Text(name).fontColor(this.currentIndex === index ? '#3ECF69' : '#bfbfbf').fontSize(18).margin({ bottom: 3 })
    }.alignItems(HorizontalAlign.Center).width('100%')
  }

  build() {
    Tabs({ barPosition: BarPosition.End }) {
      TabContent() {
        Column() {
          Row() {
            Image($r('app.media.search'))
              .width(26)
              .height(26)
              .objectFit(ImageFit.Cover)
              .margin({ left: 10 })

            TextInput({ placeholder: '请输入运动名称' })
              .width('60%')
              .height(30)
              .backgroundColor(Color.White)
              .onChange((value: string) => {
                this.search_item = value
              })

            Blank()

            Button('搜索')
              .backgroundColor('#3ECF69')
              .borderRadius(30)
              .fontSize(15)
              .fontColor(Color.White)
              .height(30)
              .width('20%')
              .margin({ left: 8, right: 3, top: 3, bottom: 3 })
              .onClick(() => {
                router.push({
                  url: 'pages/search_result',
                  params: {
                    sports: this.search_item
                  }
                })
              })
          } //search
          .borderColor('#3ECF69')
          .borderWidth(2)
          .borderRadius(50)
          .backgroundColor(Color.White)
          .width('90%')
          .height(40)
          .margin({ top: 5, bottom: 5, left: 5, right: 5 })

          SportsCategory({ sportsItems: this.sportsItem ,RecordSports:$RSports,RecordDataArray:$RDArray})
        }
        .backgroundImage($r('app.media.background'))
        .backgroundImageSize({ width: '100%', height: '100%' })
      }.tabBar(this.bottomBarBuilder('主页', $r('app.media.index'), $r('app.media.indexgray'), 0))

      TabContent() {
        Column() {
          if (this.RDArray.length != 0) {
            RecordGrid({RecordDataArray:$RDArray,RecordSports:$RSports})
          }
          else {
            Text('暂无运动记录').fontSize(19).width('100%').height(20).margin({ top: 12, left: 20 })
          }
        }
        .width('100%')
        .height('100%')
        .backgroundImage($r('app.media.background2'))
        .backgroundImageSize({ width: '100%', height: '100%' })

      }.tabBar(this.bottomBarBuilder('记录', $r('app.media.statistics'), $r('app.media.statisticsgray'), 1))
    }
    .onChange((index: number) => {
      this.currentIndex = index;
    })
  }
}

三、搜索结果界面

1、接收页面路由的传参,并初始化工程内的运动项数据,便于遍历查找。

import router from '@ohos.router';
import { initializeOnStartup } from '../model/SportsDataModels'
import { SportsData,RecordData } from '../model/SportsData'
import { SportsGrid,RDArray,RSports } from './SportsCategoryList'

@Entry
@Component
struct Search_result {
  @State name:string = router.getParams()['sports']
  private sportsItem: SportsData[] = initializeOnStartup()
  private ResultDataArray: Array<SportsData> = []
...
}

由于有的运动项目名称相同,但配速不同,因此在设置字符串匹配判断时取字符串的子串来匹配。

  aboutToAppear() {
    let item;
    for (item of this.sportsItem) {
      if (item.name.length >= this.name.length) {
        if (this.name == item.name.substring(0, this.name.length)) {
          this.ResultDataArray.push(item);
        }
      }
      else {
        if (this.name == item.name) {
          this.ResultDataArray.push(item);
        }
      }
    }
  }

将SportsCategoryList中的SportsGrid组件用export修饰,就能在搜索结果界面使用了,将搜索的结果用数组存放,接着传参进SportsGrid进行列表渲染。

  build() {
    Column() {
      PageTitle({ title: '搜索结果' })
      Row() {
        Image($r('app.media.search'))
          .width(26)
          .height(26)
          .objectFit(ImageFit.Cover)
          .margin({ left: 10 })

        TextInput({placeholder:'请输入运动名称'})
          .width('60%')
          .height(30)
          .backgroundColor(Color.White)

        Blank()

        Button('搜索')
          .backgroundColor('#3ECF69')
          .borderRadius(30)
          .fontSize(15)
          .fontColor(Color.White)
          .height(30)
          .width('20%')
          .margin({ left: 8, right: 3, top: 3, bottom: 3 })
          .onClick(() => {
            router.push({
              url: 'pages/search_result',
              params: {
                sports: this.sportsItem
              }
            })
          })
      } //search
      .borderColor('#3ECF69')
      .borderWidth(2)
      .borderRadius(50)
      .backgroundColor(Color.White)
      .width('90%')
      .height(40)
      .margin(5)

      Scroll() {
        Column() {
          if (this.ResultDataArray.length != 0) {
            SportsGrid({ sportsItems: this.ResultDataArray })
          }
          else {
            Text('没有查到与此相关的结果').fontSize(19).width('100%').height(20).margin({ top: 12, left: 20 })
          }
        }
      }
      .scrollBar(BarState.Off)
    }.height('100%')
    .width('100%')
    .backgroundImage($r('app.media.background'))
    .backgroundImageSize({ width: '100%', height: '100%' })
  }
}

@Component
struct PageTitle {
  private title: string

  build() {
    Flex({ alignItems: ItemAlign.Start }) {
      Image($r('app.media.Back'))
        .width(21.8)
        .height(19.6)
      Text(this.title)
        .fontSize(21.8)
        .margin({ left: 17.4 })
    }
    .height(61)
    .padding({ top: 15, bottom: 10, left: 28.3 })
    .onClick(() => {
      router.back()
    })
  }

结语

以上就是本次的小分享啦!❀❀

更多资料请关注我们的项目 : Awesome-Harmony_木棉花

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
SportsDemo.zip 9.09M 38次下载
已于2022-10-15 17:32:32修改
3
收藏 1
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

各个文件讲解用不同的颜色标出很赞

回复
2022-10-17 14:19:10
木棉花潘颖琳
木棉花潘颖琳 回复了 红叶亦知秋
各个文件讲解用不同的颜色标出很赞

👍感谢支持

回复
2022-10-17 18:09:52
回复
    相关推荐