鸿蒙期末个人项目“黑马健康”——项目阶段五:多设备响应式布局

目录

项目介绍:

分析:

页面实现效果:

重点实现:

阶段项目代码:


项目介绍:

    黑马健康软件是一款基于全民健康的软件,主要有三个页面组成,分别是欢迎页面,统计记录页面,食物列表页面。

分析:

       利用mediaQuery设置媒体的查询条件,设置对屏幕宽度做查询,根据屏幕的不同宽度的不同范围,划分大值的区分范围来区别设备,每个范围指定一个对应的字符串状态,分别是:sm、md、lg。之后给设备查询的监听器设置回调函数,当媒体状态发生变更时,三个设备的监听器便会被触发,通过回调函数改变状态,作为设备标记保存在AppStorage中。之后页面变回利用@StorageProp读取当前设备标记,之后页面组件的属性中就可以通过设备标记来实现不同设备的渲染,达到响应式布局的效果。

页面实现效果:

手机设备的实现效果:

折叠手机的实现效果

平板的实现效果:

重点实现:

1.为了优雅的去传值,不用下面所述的这种声明对象方式

  //根据设备选择导航的布局
  // chooseBarPosition(){
  //   //定义对象,根据对象名key来返回值
  //   return new BreakpointType({
  //     sm:BarPosition.End,
  //     md:BarPosition.Start,
  //     lg:BarPosition.Start
  //   }).getValue(this.currentBreakpoint)
  //   // let p = {
  //   //   sm: BarPosition.End,
  //   //   md:BarPosition.Start,
  //   //   lg:BarPosition.Start
  //   // }
  //   // return p[this.currentBreakpoint]
  //
  // }

定义一个封装接口,这个接口的类型和里面参数的类型都是泛型,因为后续的属性中的定义有的是传递这个属性中的对象的属性,有的是传递的布尔类型的值等等,并且防止有的不用传值的情况,这里的参数是可传可不传的泛型类型。

2.仿照上述页面渲染的方法,将平板的Swiper组件的穿梭框样式隐藏:

效果展示:

阶段项目代码:

/**
 * 首页开发
 */
import BreakpointType from '../common/bean/BreanpointType'
import BreakpointConstants from '../common/constants/BreakpointConstants'
import { CommonConstants } from '../common/constants/CommonConstants'
import BreakpointSystem from '../common/utils/BreakpointSystem'
import RecordIndex from '../view/record/RecordIndex'

@Entry
@Component
struct Index {

  //定义状态变量来记录当前的页面下标
  @State currentIndex:number = 0

  private breakpointSystem:BreakpointSystem = new BreakpointSystem()
  //TODO 这个装饰器是啥 定义当前的设备并初始化
  @StorageProp('currentBreakpoint') currentBreakpoint:string = BreakpointConstants.BREAKPOINT_SM

  //定义内部构造函数,参数直接传题目,图片,下标
  @Builder TabBarBuilder(title:ResourceStr,image:ResourceStr, index:number){
    Column({space:CommonConstants.SPACE_8}){
      Image(image)
        .width(22)
        .fillColor(this.selectColor(index))
      Text(title)
        .fontSize(14)
        .fontColor(this.selectColor(index))
    }
  }
  aboutToAppear(){
    //在build函数加载前就注册设备监听
    this.breakpointSystem.register()
  }
  aboutToDisappear(){
    //在退出应用时取消注册
    this.breakpointSystem.unregister()
  }
  //封装颜色选择
  selectColor(index){
    return this.currentIndex ===  index ? $r('app.color.primary_color'):$r('app.color.gray')
  }
  //根据设备选择导航的布局
  // chooseBarPosition(){
  //   //定义对象,根据对象名key来返回值
  //   return new BreakpointType({
  //     sm:BarPosition.End,
  //     md:BarPosition.Start,
  //     lg:BarPosition.Start
  //   }).getValue(this.currentBreakpoint)
  //   // let p = {
  //   //   sm: BarPosition.End,
  //   //   md:BarPosition.Start,
  //   //   lg:BarPosition.Start
  //   // }
  //   // return p[this.currentBreakpoint]
  //
  // }
  build() {
    //让导航栏位于页面底部
    //根据设备选择导航的布局
    Tabs({barPosition: BreakpointConstants.BAR_POSITION.getValue(this.currentBreakpoint)}){
      TabContent(){
        // 饮食记录页面
        RecordIndex()

      }.tabBar(this.TabBarBuilder($r('app.string.tab_record'),$r('app.media.ic_calendar'),0))
      TabContent(){
        Text('发现页面')
      }.tabBar(this.TabBarBuilder($r('app.string.tab_discover'),$r('app.media.discover'),1))

      TabContent(){
        Text('我的主页')
      }.tabBar(this.TabBarBuilder($r('app.string.tab_user'),$r('app.media.ic_user_portrait'),2))



    }
    .width('100%')
    .height('100%')
    .vertical(new BreakpointType({
      //传参
      sm:false,
      md:true,
      lg:true
    }).getValue(this.currentBreakpoint))
    .onChange(index => this.currentIndex = index)//也可以直接对TabBarBuilder加点击事件
  }
}

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'
import NutrientStats from './NutrientStats'
@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.ic_public_spinner'))
            .width(20)
            .fillColor($r('app.color.secondary_color'))

        }
          .padding(CommonConstants.SPACE_8)
          .onClick(()=>{
            this.controller.open()
          })

        // 2.统计信息
        Swiper(){
          // 2.1 热量统计
          CalorieStats()
          // 2.2 营养素统计
          NutrientStats()

        }
        .width('100%')
        .backgroundColor(Color.White)
        .borderRadius(CommonConstants.DEFAULT_18)
        .indicatorStyle({selectedColor:$r('app.color.primary_color')})//  设置穿梭框的样式
        .indicator(new BreakpointType({
          //为平板设备隐藏穿梭框
          sm:true,
          md:true,
          lg:false
        }).getValue(this.currentBreakpoint))
        .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)
  }
}

参考黑马课堂老师的讲解,欢迎大家的批评和指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值