鸿蒙期末个人项目-黑马健康——项目阶段八:发现页面和我的页面UI界面以及功能部署

目录

项目介绍:

页面布局:

分析:

发现页面UI设计:

我的页面UI设计:

登录页面UI设计:

健康信息页面UI设计:

页面实现效果:

出现的问题与解决:

阶段项目代码:

发现页面代码:

 我的页面代码:

登录页面代码:

健康信息页面代码:


项目介绍:

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

页面布局:

分析:

发现页面UI设计:
  • 总体是一个列式布局,第一行是一有两个文本组件构成,第二行是由list组件构成的一个水平滑动样式,第三行是有两个文本组成,最后是由list组件渲染的列式布局样式
我的页面UI设计:
  • 总体是列式布局,第一行是有两个Image组件构成,其中一个是之前在食物列表页面用到的消息的渲染效果,另一个是一个设置按钮,点击按钮之后,会弹出一个panel弹窗,在这里可以点击换字体大小,实现全局变化字体大小的效果,并实现用户持久化;第二行是一个有Image组件和Text组件渲染的用户登录的样式,点击后,可以跳转到用户登录注册的界面(这里只实现了用户的登录),输入信息后,点击“登录”按钮,即可跳转回首页,并且输入的账号等登录成功的信息也会传递回来,并且重新进行登录注册组件的渲染。第三行是一个关于健康数据的组件,由Image组件和Text组件构成,点击后可以跳转到健康数据页面。最后一行是由List组件循环渲染的应用功能的组件。
登录页面UI设计:
  • 登录页面是一个列式布局,第一行是由Image组件构成的登录标识,第二行是一个文本组件,第三行和四行分别是输入的用户名和密码,最后一行是登录和注册的按钮;
健康信息页面UI设计:
  • 总体是列式布局,首部是有两个Image组件构成,其中一个是退出此页面,返回主页面的退回图片,下面的部分是由一个网格Grid组件构成的,用ForEach循环渲染健康信息。

页面实现效果:

出现的问题与解决:

  • 当不给这一行设定宽度的时候,Blank()组件是不起作用的

分配宽度之后:

  • 调用子组件时一直报错,但是不妨碍功能的使用,图片能正常加载

尝试了很多遍,官方论坛里看还是没有解决

解决方式就是关闭编译器重新打开,不报错了

  • 发现页面的主题推荐,加载不出图片和文字资源。检查之后,发现是构造函数的赋值错误

改动之后:图片资源和文字资源正确加载

  • 如果使用@Consume和@Provide来传递数据,只能在父子组件之间进行传递,不能在同一等级之间传递
  • 出现了运行时异常,在main_pages.json配置的必须是一个页面,带有@entry装饰器

  •  这里click使用的装饰器是@link,就不能使用 this. 去传递参数,应该使用$传递参数

  • 当未登录是不能获取到页面跳转所传递过来的值,加上条件判断,等点击登录按钮,并且传递过来当定义的@State修饰的状态变量仍是false的时候才获取数据否则不会获取数据,并且将这两个变量实现持久化。 出现的问题仍旧如下:

但是经过console.log后发现数据都传递过来了,

但是在用户登录的界面偶尔渲染不上,(那种感觉好像是页面渲染和数据的传递在竞速)并且出现了一些bug,就是当实现登录后,点击退出,再次进入该应用时,就会发生一些运行时异常,直接卡退。

经过从头的梳理分析,发现在页面跳转获取数据时有逻辑上的问题,很可能没有执行登录,就去获取登录页面穿过来的值,这样就会导致卡退。解决办法就是使用一些状态参数来控制传值,当点击登录并且登录成功时,才会去获取数据,进行数据传递和页面的渲染,在登录成功之后,就会将后面页面渲染所要用到的数据实现持久化处理,并且状态参数也会实现持久化处理。

阶段项目代码:

发现页面代码:

import { CommonConstants } from '../../common/constants/CommonConstants'
import FunctionList from './FunctionList'
import RecommendTheme from './RecommendTheme'
import ThemeInfo from './ThemeInfo'


/**
 * 发现页面
 */
@Component
export default struct FindPage {
  @Consume fontSize:number
  build() {

    Column({ space: CommonConstants.SPACE_8 }) {
      // 1.推荐主题
      Row() {
        Text('推荐主题')
          .fontWeight(CommonConstants.FONT_WEIGHT_700)
          .fontSize(this.fontSize+4)
        Blank()
        Text('更多')
      }
      .width(CommonConstants.THOUSANDTH_940)
      .margin({ top: 10, bottom: 10 })

      // 2.主题展示
      Row({space:CommonConstants.SPACE_4}){
        RecommendTheme()
      }
      .backgroundColor(Color.White)
      .width(CommonConstants.THOUSANDTH_940)
      .height(210)
      .borderRadius(CommonConstants.DEFAULT_18)
      .justifyContent(FlexAlign.SpaceEvenly)
      .margin({ bottom: 10 })


      // 3.功能管理
      Row() {
        Text('功能管理')
          .fontWeight(CommonConstants.FONT_WEIGHT_700)
          .fontSize(this.fontSize+4)
        Blank()
        Image($r('app.media.sort'))
          .width(18)

      }
      .width(CommonConstants.THOUSANDTH_940)
      .margin({ top: 10, bottom: 10 })

      // 4.功能列表
      FunctionList()
        .layoutWeight(1)
        .margin({left:5})

   }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_page_background'))

  }
}

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

@Component
export default struct RecommendTheme {

   themeList: Array<ThemeInfo> = [
    new ThemeInfo('绿泡泡', $r('app.media.background_green')),
    new ThemeInfo('粉色回忆', $r('app.media.background_pink')),
    new ThemeInfo('色彩碰撞', $r('app.media.background_color')),
    new ThemeInfo('清凉一夏', $r('app.media.bacground_color2')),
    new ThemeInfo('黑夜骑士', $r('app.media.background_color3')),
    new ThemeInfo('甜美西瓜', $r('app.media.background_color4')),
    new ThemeInfo('璀璨星河', $r('app.media.background_color5')),
  ]
  build() {
    List(){
      ForEach(this.themeList,(item:ThemeInfo)=>{
        ListItem(){
          Column({space:CommonConstants.SPACE_4}){
            Image(item.images)
              .width(120)
              .aspectRatio(0.7)
              .borderRadius(CommonConstants.DEFAULT_18)
              .shadow({radius: 6, color:'#000000',offsetX:4,offsetY:4})
            Text(item.name)
              .fontWeight(20)

          }
        }.margin({left:7,right:5,top:10})


      })
    }.listDirection(Axis.Horizontal)//图片水平摆放
  }
}

import { CommonConstants } from '../../common/constants/CommonConstants'
import ThemeInfo from './ThemeInfo'
@Component
export default struct  FunctionList{
  @Consume fontSize:number
  themeList: Array<ThemeInfo> = [
    new ThemeInfo('消息通知', $r('app.media.fun_1')),
    new ThemeInfo('闹钟', $r('app.media.fun_2')),
    new ThemeInfo('名片', $r('app.media.fun_3')),
    new ThemeInfo('查找设备', $r('app.media.fun_4')),
    new ThemeInfo('遥控拍照', $r('app.media.fun_5')),
    new ThemeInfo('天气推送', $r('app.media.fun_6')),
    new ThemeInfo('音乐', $r('app.media.fun_7')),
    new ThemeInfo('常用联系人', $r('app.media.fun_8')),
    new ThemeInfo('健康提醒', $r('app.media.fun_9')),
    new ThemeInfo('其他功能', $r('app.media.fun_10')),
  ]
  build() {
    List(){
      ForEach(this.themeList,(item:ThemeInfo)=>{
        ListItem(){
          Row({space:CommonConstants.SPACE_8}){
            Image(item.images)
              .width(35)
              .height(35)
              .margin({left:7,right:15})

              .borderRadius(CommonConstants.DEFAULT_18)
              // .shadow({radius: 6, color:'#000000',offsetX:4,offsetY:4})
            Text(item.name)
              .fontWeight(26)
              .fontSize(this.fontSize-2)


          }
          .padding(8)
          .backgroundColor(Color.White)
          .borderRadius(CommonConstants.DEFAULT_18)
          .width(CommonConstants.THOUSANDTH_940)
          .height(50)
        }.margin({left:12,right:5,top:2,bottom:8})
      })
    }
  }
}
 我的页面代码:

import router from '@ohos.router'
import preferences from '@ohos.data.preferences'
import { CommonConstants } from '../../common/constants/CommonConstants'
import ChangePanel from '../../viewmodel/ChangePanel'
import AppSetting from './AppSetting'
import MyPageHeader from './MyPageHeader'
import preferencesUtil from '../../common/utils/preferencesUtil'

/**
 * 我的页面
 */

@Component
export default struct MyPage {
   days:number = 1

  @Consume showPanel:number
  @Consume fontSize:number
  @Prop username:string
  @Prop hasLogin:boolean
  @Link clickLogin:boolean
  @State user_name:string = '用户请登录'
  @State welcome_use:string = '请注册/登录使用~'


  build() {

    Column({space:CommonConstants.SPACE_8}){
      // 1.我的页面首部
      MyPageHeader()

      // 2.用户的登录注册
        Row(){

          if(!this.hasLogin){
            Image($r('app.media.entry'))
              .width(70)
              .fillColor(Color.Red)
              .margin({right:10})
          }else{
            Image($r('app.media.user_img'))
              .width(70)

              .margin({right:10})
          }


          Column(){
            if(this.hasLogin){

              Text('ID:  '+this.username)
                .fontWeight(CommonConstants.FONT_WEIGHT_600)
                .fontColor(Color.Red)
                .fontSize(this.fontSize+4)

              Text('欢迎使用黑马健康!')
                .fontColor($r('app.color.light_gray'))
                .fontSize(this.fontSize-2)
            }else{
              Text(this.user_name)
                .fontWeight(CommonConstants.FONT_WEIGHT_600)
                .fontColor(Color.Red)
                .fontSize(this.fontSize+4)

              Text(this.welcome_use)
                .fontColor($r('app.color.light_gray'))
                .fontSize(this.fontSize-2)
            }

          }
        }
        .padding(10)
        .height('100')
        .width(CommonConstants.THOUSANDTH_940)
        .justifyContent(FlexAlign.Start)
        .margin({bottom:13,top:6})
        .backgroundColor($r('app.color.White_Color'))
        .borderRadius(CommonConstants.DEFAULT_10)
        .onClick(()=>{
          //当点击登录时,首先将this.clickLogin ,this.hasLogin的状态写进首选项
          console.log('成功点击登录'+'testTag')
          this.clickLogin = true
          preferencesUtil.putPreferenceValue('UserLoginInfo','clickVictoryInfo',this.clickLogin)
          this.hasLogin = false
          preferencesUtil.putPreferenceValue('HasLogin','HasLoginInfo',this.hasLogin)
          router.pushUrl({
                url:'pages/LoginPage'
          })

        })
        // 3.健康使用
        // 覆盖的功能
      Row({space:CommonConstants.SPACE_8}){
        Column({space:CommonConstants.SPACE_8}){
          //您已健康使用多少天?点击查看健康数据
          Text(`您已健康使用 ${this.days} 天`)
            .fontSize(this.fontSize+4)
            .fontWeight(CommonConstants.FONT_WEIGHT_600)
            .fontColor(Color.White)
          Text('点击查看您的健康信息')
            .fontSize(this.fontSize-2)
            .fontColor(Color.White)
        }
        Blank()
       Image($r('app.media.healthInfo'))
         .width(60)


      }
      .padding(10)
      .width(CommonConstants.THOUSANDTH_940)
      .height(80)
      .backgroundColor($r('app.color.primary_color'))
      .borderRadius(CommonConstants.DEFAULT_18)
      .shadow({radius: 6, color:'#000000',offsetX:7,offsetY:10})
      .onClick(()=>{
        router.pushUrl({
          url:'pages/HealthStatisticPage'
        })
      })

      //VIP设置
      Row({space:CommonConstants.SPACE_8}){
        Column({space:CommonConstants.SPACE_8}){
          Text('升级VIP享更多专属权限')
            .fontSize(this.fontSize+2)
            .fontWeight(CommonConstants.FONT_WEIGHT_600)
            .fontColor(Color.White)
          Text('升级VIP享更多专属权限')
            .fontSize(this.fontSize-2)
            .fontColor(Color.White)
        }
        Blank()
        Button('去升级')
          .type(ButtonType.Capsule)
          .fontColor($r('app.color.primary_color'))
          .backgroundColor(Color.White)

      }
      .padding(10)
      .width(CommonConstants.THOUSANDTH_940)
      .height(80)
      .backgroundColor($r('app.color.primary_color'))
      .borderRadius(CommonConstants.DEFAULT_18)
      .shadow({radius: 6, color:'#000000',offsetX:7,offsetY:10})

      // 4.应用的设置等
        AppSetting()
          .layoutWeight(1)

      if(this.showPanel===1){
        ChangePanel()
          .transition({
            translate: { y: 115 }
          })
          .layoutWeight(1)
      }



    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_page_background'))
  }
}
import { CommonConstants } from '../../common/constants/CommonConstants'

@Component
export default struct MyPageHeader {
  @Consume showPanel:number


  build() {
    Column(){
      // 1.设置按钮和信息
      Row({space:CommonConstants.SPACE_10}){
        Blank()
        Image($r('app.media.setting')).width(28).margin({right:10})
          .onClick(()=>{
            this.showPanel = -this.showPanel
            console.log("弹窗显示成功",'testTag')
          })
        Badge({count:1,position:BadgePosition.RightTop,style:{fontSize:12}}){

          Image($r('app.media.ic_public_email'))
            .width(28)
        }

      }
      .width(350)
      .margin({top:7})
      .height(30)
    }

  }
}
登录页面代码:

import router from '@ohos.router'
import prompt from '@ohos.prompt'
import { CommonConstants } from '../common/constants/CommonConstants'
import preferencesUtil from '../common/utils/preferencesUtil'

@Entry
@Component
struct LoginPage {
  @State username:string = ''
  @State password:string = ''
  @State hasLogin:boolean = false


  build() {
    
      Image($r('app.media.login_img'))
        .width(60)
        .margin({top:160,bottom:10})
      Text('欢迎登录')
        .fontWeight(CommonConstants.FONT_WEIGHT_600)
        .fontSize(30)
      Row(){
        Text('用户名:').fontWeight(CommonConstants.FONT_WEIGHT_600).fontSize(18)
        TextInput({placeholder:'请输入用户名:'})
          .margin({top:20,bottom:15})
          .width(250)
          .height(40)
          .fontColor(Color.Blue)
          .onChange((value:string)=>{
            this.username = value
          })
        }.width(300)

      Row(){
        Text('密   码:').fontWeight(CommonConstants.FONT_WEIGHT_600).fontSize(18)
        TextInput({placeholder:'请输入密码:'})
          .type(InputType.Password)
          .width(250)
          .height(40)
          .fontColor(Color.Blue)
          .onChange((value:string)=>{
            this.password = value
          })
      }.width(300)
      Row({space:CommonConstants.SPACE_12}){
        Button('登录')
          .type(ButtonType.Capsule)
          .fontSize(18)
          .backgroundColor($r('app.color.primary_color'))
          .onClick(()=>{

            // router.back()
            //如果输入的用户名或者密码为空,则提示
            if(this.username==='' || this.password ===''){
              //登录失败

              prompt.showToast({
                message:"账号和密码均不可以为空!"
              })
            }else{
              //登录成功
              this.hasLogin = true
              console.log('hasLogin:'+this.hasLogin.toString()+'testTag')
              console.log('username:'+this.username.toString()+'testTag')
              //将已经登录成功的信息写入首选项
              preferencesUtil.putPreferenceValue('HasLogin','HasLoginInfo',this.hasLogin)

              router.replaceUrl({
                url:'pages/Index',
                params:{
                  username:this.username,
                }
              })

            }


          })
        Button('注册')
          .type(ButtonType.Capsule)
          .fontSize(18)
          .backgroundColor($r('app.color.light_gray'))


      }.margin({top:30})

    }
    .backgroundColor($r('app.color.index_page_background'))
    .height('100%')
    .width('100%')
  }

}
健康信息页面代码:
import router from '@ohos.router'
import { CommonConstants } from '../common/constants/CommonConstants'
import preferencesUtil from '../common/utils/preferencesUtil'
import HealthComponent from '../view/health/HealthComponent'
@Entry
@Component
struct HealthStatisticPage {
  @State hasLogin:boolean = false
  async aboutToAppear(){
    //将登录成功的值从用户首选项中取出来
    this.hasLogin = await preferencesUtil.getPreferenceValue('HasLogin','HasLoginInfo',false) as boolean
  }
  build() {

    Column({space:CommonConstants.SPACE_10}){
      Row({space:CommonConstants.SPACE_10}){
        Image($r('app.media.ic_public_back')).width(40)
          .onClick(()=>{
            router.back()
          })
        Text('健康').fontSize(20)
        Blank()
        if(this.hasLogin){
          Image($r('app.media.user_img')).width(40)
        }else{
          Image($r('app.media.entry')).width(40)
        }
      }
      .width(CommonConstants.THOUSANDTH_940)
      .margin({top:10})
      //网格记录项,祥康组件
      HealthComponent()
            .layoutWeight(1)

    }.width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_page_background'))
  }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值