鸿蒙NEXT开发浅进阶到精通11:我的开发项目中遇到的问题及解决笔记02

145 阅读6分钟

写在前面

不得不说摸鱼的程序员所在的公司,不是工资低就是快倒闭啊,(某些机构除外),上周做完一个模板项目后,端午节后我们就开启了客户定制的鸿蒙化开发,在这里我今天的笔记又起到了用途,今晚下班前又做了上个项目我遇到的一些总结,我们后面第三或第四篇发出,不着即凹。

一、解决scroll内嵌column内容较少时不能充满屏幕而内容居中

由于在遥远的2024年5月份,在上架审核时,还会考虑APP对小窗和悬挂状态下的UI适配,不得不说那时候的hw还是对上架应用要求极高的,考虑的状态很高,不过在今年初,如果你的应用或者元服务没有悬挂和小窗使用场景,审核不会刻意要求,这也展现了鸿蒙的包容性与人性化,但是在那是凹,想要小瓶或悬挂适配,scroll是必备组件,因为list组件虽然也可以在高度不够时进行滚动,但并不通用。

那么在不是小窗悬挂状态时,也就是正常态,在scroll里内嵌column中,如果内容不多他是不居上的,于是我们内嵌了column,这时候就有土方法,放一个空子组件进去,Blank()再结合自适应拉伸属性Blank().layoutWeight(1)还是极好用的,如果占用了底部导航条也可再加个Blank().height(5)来试。

二、关闭分屏能力

这个经常被用各种状态窗口或者多端适配时的使用,强制不会分屏能少很多事也不会导致UI混乱, 优化起来麻烦,可能会考虑直接不用分屏 在模块的module.json5中,指定其他能力,但不指定分屏split,,下面是指定不全屏,但不影响代码给某个页面单次打开全屏

"supportWindowMode": ['split',"floating","全屏"]

三、时间戳转化格式化时间格式,单月前有 0的情况

直接找dayjs包吧,自己封装整理需要考虑单月-单小时,分钟,秒前面都有0的情况没考虑到 2012-07-02 23:06:39

 

  function getTimeStamps() {
  let date = new Date();
  let key =
    (date.getFullYear().toString() + '-' +
      (date.getMonth() <= 8 ? '0' + (date.getMonth() + 1).toString() : (date.getMonth() + 1).toString())
      + '-' + date.getDate().toString() + ' ' +
    date.getHours().toString() + ':' + date.getMinutes()
      .toString() + ':' + date.getSeconds().toString()).toString();
  return key
}

四、防止按钮短时间二次点击,影响请求

就是多设置一个布尔值,在请求成功或确定出错后才可以解除,否则请求点击一次后,那个按钮属性enabled都是不可点击不可选的在请求成功前控制支付宝支付是否可点击, 点击后为false,成功和各种错误结束时为true

@State canClicked: boolean = true //在请求成功前控制支付宝支付是否可点击, 点击后为false,成功和各种错误结束时为true
@State loading: boolean = false //

如果你知道一个东西叫防抖,也是极好的,上面是一个更简单思维直接的布尔控制,好在很有效,不用纠结代码是否高端,有用即可。那么防抖使用setTimeout来控制,代码是什么呢?相信评论区的你是有答案的,很期待交流哈哈。

五、 鸿蒙自带的列表弹窗

1.png

列表目录也是很常见的移动端需求,这里先给出鸿蒙官方的文档案例,也很直观,当时也是靠着这个给解决了,没有耽误项目进度。 developer.huawei.com/consumer/cn…

developer.huawei.com/consumer/cn…


Row() {
  Text(this.chargeMoney).fontColor(Color.White)
    .bindMenu(this.MunmItem(['1元', '5元', '10元'], 1, '请选择充电金额'))
  Text('智能充满自停').fontColor(Color.White)
  Text(this.chargeTime)
    .fontColor(Color.White)
    .bindMenu(this.MunmItem(['30分钟', '60分钟', '120分钟'], 2, '请选择充电时间'))
}.width('80%')
.justifyContent(FlexAlign.SpaceEvenly)

//列表结构
@Builder
MunmItem(fList: string[], Typeindex: number, title: string) {

  List() {
    ListItem() {
      Row() {
        Text(title)
          .fontColor(Color.Blue)
          .padding(15)
          .fontWeight(500)
      }.width('100%')
      .justifyContent(FlexAlign.Start)
      // .backgroundColor(Color.Red)
      .borderRadius(15)

    }

    ForEach(fList, (item: string) => {
      ListItem() {
        Row() {
          Text(item)

        }.width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .padding(15)
        .onClick(() => {
          if (Typeindex === 1) {
            this.chargeMoney = item
            this.chargeTime = '按时间'
          }
          if (Typeindex === 2) {
            this.chargeTime = item
            this.chargeMoney = '按金额'
          }
        })
      }
    })
  }.width('100%')
  .divider({ strokeWidth: 1 })
}

六、多个半模态重合出现-使用自定义结构弹出

我们前面文章里提到使用布尔数据映射给每个复杂数据类型,做单个半模态展示,这里还有我早起的一个解决方案,那就是不使用鸿蒙自带的半模态组件,而是封装一个弹窗结构,也是很好的解决方案,这里底层的区别,有兴趣的话可以评论区留言我们单独分析一下呢。

//点击某个单元的弹框信息
UnitHouseDialogCOm({
  isShowUnit: this.isShowUnit,
  Uintinfo: this.Uintinfo,
  unitHouseList: this.unitHouseList,
  // searchIn: this.searchIn,
  isresidentList: this.isresidentList,
  communityItem: this.paramsLouDong.communityItem
})
  .visibility(this.isShowUnit ? Visibility.Visible : Visibility.Hidden)
  
 .beenSheet()

UnitHouseDialogCOm是我自己封装的一个组件,大家有兴趣可以下载鸿蒙版 业主贝贝APP 看下选择地址,精确到单元楼的弹窗。

七、Tab菜单案例1

我在鸿蒙前接触过一段时间的简单前端,基本都是政府项目的网页系统,这种项目除了加密做好外,基本不怎么花哨和秀UI渲染手法,能用安全即可,不过接触鸿蒙后,给我极其直观的感受是,鸿蒙的tab组件不仅单个好用,而且还可套娃使用,在国博项目中我们使用ASCF框架开发适配,在遇到多重目录时,我就在感慨如果使用纯ArkTS来开发这个就很好做了,因为可以多重套娃,只要你在编程时自己理清层级即可,但是在国博的藏品tab模块中,使用hxml类web语言开发时,又不能使用uniapp和小程序wxml的组件库的情况下,使用早期的jQuery时代编程还是比较棘手和繁琐的,巧的是我来分配任务,给我们一个全栈和10年iOS老哥们去做了,效果也还不错,有兴趣大家可以加载国家博物馆元服务查看藏品菜单看下那个三级菜单筛选的巧妙繁琐实现

这里代码案例是2024年一个项目中遇到的场景,看图大家就明白了

2.png

  .width('100%')
    .layoutWeight(1)
    .barWidth('90%')
    .borderRadius(10)
    .barHeight(30)
    .barBackgroundColor(Color.White)
    .onChange((index) => {
      this.orderPageNum = 1 //避免客户在我的订单看到了第二页而切换他人订单列表,查看到的就是第二页内容了,没有从头看完他人订单
      this.repairHisList = []
      this.currentIndex = index
      this.isLastPage = false
      this.getRepairQueryRecordList()

    })
  }
  .height('100%')
  .width('100%')
}

@Builder
TabBarCustermBuilder(title: string, xuhao: 0 | 1) {
  Column() {
    Text(title)
      .width('100%')
      .fontColor('')
      .align(Alignment.Center)
      .textAlign(TextAlign.Center)
      .borderRadius(5)
      .backgroundColor(this.currentIndex == xuhao ? Color.White : '#efefef')
  }.backgroundColor('#efefef')
  .width('100%')
  .padding(1)
  .borderRadius({
    topLeft: xuhao == 0 ? 5 : 0,
    bottomLeft: this.currentIndex == xuhao ? 5 : 0,
    topRight: xuhao == 1 ? 5 : 0,
    bottomRight: xuhao == 1 ? 5 : 0
  })

这里有两处需要注意的地方,就是一般这场景是需要做分页加载的,当你切换tab的时候,需要将请求数据的page参数归1,不然容易出现漏加载数据的情况,当然你做两个page变量也可以实现切换后每个菜单区都独立进行分页加载,


this.orderPageNum = 1 
    //避免客户在我的订单看到了第二页而切换他人订单列表,查看到的就是第二页内容了,没有从头看完他人订单
    this.repairHisList = []

写在后面

哎呀今天又又一次回看了一年前的笔记,很多开发中与同事相处的场景也历历在目,当然也再次熟悉了一些散碎的实战开发知识点,希望对大家开发之路有那么一点帮助。 如果你已经看到这里啦,不仿点个赞吧。