0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙OS开发:典型页面场景【一次开发,多端部署】实战(音乐专辑页2)

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-05-25 16:47 次阅读

一多音乐专辑主页

介绍

本示例展示了音乐专辑主页。

  • 头部返回栏: 因元素单一、位置固定在顶部,因此适合采用自适应拉伸,充分利用顶部区域。
  • 专辑封面: 使用栅格组件控制占比,在小尺寸屏幕下封面图与歌单描述在同一行。
  • 歌曲列表: 使用栅格组件控制宽度,在小尺寸屏幕下宽度为屏幕的100%,中尺寸屏幕下宽度为屏幕的50%,大尺寸屏幕下宽度为屏幕的75%。
  • 播放器: 采用自适应拉伸,充分使用底部区域。

本示例使用[一次开发多端部署]中介绍的自适应布局能力和响应式布局能力进行多设备(或多窗口尺寸)适配,保证应用在不同设备或不同窗口尺寸下可以正常显示。

用到了媒体查询接口[@ohos.mediaquery]。

效果预览

本示例在预览器中的效果:

本示例在开发板上运行的效果:

image.png

使用说明:

1.启动应用,查看本应用在全屏状态下的效果。

2.在应用顶部,下滑出现窗口操作按钮。(建议通过外接鼠标操作,接入鼠标只需要将鼠标移动至顶部即可出现窗口)

3.点击悬浮图标,将应用悬浮在其他界面上显示。

4.拖动应用悬浮窗口的四个顶角,改变窗口尺寸,触发应用显示刷新。改变窗口尺寸的过程中,窗口尺寸可能超出屏幕尺寸,此时在屏幕中只能看到应用部分区域的显示。可以通过移动窗口位置,查看应用其它区域的显示。

开发前请熟悉鸿蒙开发指导文档gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

工程目录

AppMarket/entry/src/main/ets/
|---model
|   |---MediaData.ets                      // 主页用到的图片资源
|   |---SongList.ets                       // 歌曲数据
|   |---SongModule.ets                     // 事件监听函数模块
|---pages                                  
|   |---index.ets                          // 首页
|---common                                    
|   |---Content.ets                        // 内容组件
|   |---Header.ets                         // 标题栏
|   |---Player.ets                         // app模块(包含安装,展示图片,更多功能)
|   |---PlayList.ets                       // 歌单列表
|   |---PlayListCover.ets                  // 歌单封面

具体实现

本示例介绍如何使用自适应布局能力和响应式布局能力适配不同尺寸窗口,将页面分拆为4个部分。

标题栏

由于在不同断点下,标题栏始终只显示“返回按钮”、“歌单”以及“更多按钮”,但“歌单”与“更多按钮”之间的间距不同。
通过栅格实现:将标题栏划分为“返回按钮及歌单”和“更多按钮”两部分,这两部分在不同断点下占据的列数不同。

歌单封面

通过栅格实现歌单封面,它由封面图片、歌单介绍及常用操作三部分组成这三部分的布局在md和lg断点下完全相同,但在sm断点下有较大差异,[源码参考]。

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { optionList } from '../model/SongList'



@Component

export default struct PlayListCover {

  @State imgHeight: number = 0

  @StorageProp('coverMargin') coverMargin: number = 0

  @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'

  @StorageProp('fontSize') fontSize: number = 0



  @Builder

  CoverImage() {

    Stack({ alignContent: Alignment.BottomStart }) {

      Image($r('app.media.pic_album'))

        .width('100%')

        .aspectRatio(1)

        .borderRadius(8)

        .onAreaChange((oldArea: Area, newArea: Area) = > {

          this.imgHeight = newArea.height as number

        })

      Text($r('app.string.collection_num'))

        .letterSpacing(1)

        .fontColor('#fff')

        .fontSize(this.fontSize - 4)

        .translate({ x: 10, y: '-100%' })

    }

    .width('100%')

    .height('100%')

    .aspectRatio(1)

  }



  @Builder

  CoverIntroduction() {

    Column() {

      Text($r('app.string.list_name'))

        .opacity(0.9)

        .fontWeight(500)

        .fontColor('#556B89')

        .fontSize(this.fontSize + 2)

        .margin({ bottom: 10 })



      Text($r('app.string.playlist_Introduction'))

        .opacity(0.6)

        .width('100%')

        .fontWeight(400)

        .fontColor('#556B89')

        .fontSize(this.fontSize - 2)

    }

    .width('100%')

    .height(this.currentBreakpoint === 'sm' ? this.imgHeight : 70)

    .alignItems(HorizontalAlign.Start)

    .justifyContent(FlexAlign.Center)

    .padding({ left: this.currentBreakpoint === 'sm' ? 20 : 0 })

    .margin({

      top: this.currentBreakpoint === 'sm' ? 0 : 30,

      bottom: this.currentBreakpoint === 'sm' ? 0 : 20

    })

  }



  @Builder

  CoverOptions() {

    Row() {

      ForEach(optionList, item = > {

        Column({ space: 4 }) {

          Image(item.image).height(30).width(30)

          Text(item.text)

            .fontColor('#556B89')

            .fontSize(this.fontSize - 1)

        }

      })

    }

    .width('100%')

    .height(70)

    .padding({

      left: this.currentBreakpoint === 'sm' ? 20 : 0,

      right: this.currentBreakpoint === 'sm' ? 20 : 0

    })

    .margin({

      top: this.currentBreakpoint === 'sm' ? 15 : 0,

      bottom: this.currentBreakpoint === 'sm' ? 15 : 0

    })

    .justifyContent(FlexAlign.SpaceBetween)

  }



  build() {

    if (this.currentBreakpoint === 'sm') {

      Column() {

        GridRow() {

          GridCol({ span: { sm: 4, md: 10 }, offset: { sm: 0, md: 1, lg: 1 } }) {

            this.CoverImage()

          }



          GridCol({ span: { sm: 8, md: 10 }, offset: { sm: 0, md: 2, lg: 2 } }) {

            this.CoverIntroduction()

          }



          GridCol({ span: { sm: 12, md: 10 }, offset: { sm: 0, md: 2, lg: 2 } }) {

            this.CoverOptions()

          }

        }

        .margin({ left: this.coverMargin, right: this.coverMargin })

        .padding({ top: this.currentBreakpoint === 'sm' ? 50 : 70 })

      }

    } else {

      Column() {

        GridRow() {

          GridCol({ span: { sm: 4, md: 10 }, offset: { sm: 0, md: 1, lg: 1 } }) {

            this.CoverImage()

          }



          GridCol({ span: { sm: 8, md: 10 }, offset: { sm: 0, md: 2, lg: 2 } }) {

            this.CoverIntroduction()

          }



          GridCol({ span: { sm: 12, md: 10 }, offset: { sm: 0, md: 2, lg: 2 } }) {

            this.CoverOptions()

          }.margin({

            top: this.currentBreakpoint === 'sm' ? 15 : 0,

            bottom: this.currentBreakpoint === 'sm' ? 15 : 0

          })

        }

        .margin({ left: this.coverMargin, right: this.coverMargin })

        .padding({ top: this.currentBreakpoint === 'sm' ? 50 : 70 })

      }

      .height('100%')

    }

  }

}

1、在sm断点下,封面图片和歌单介绍占满12列,常用操作此时会自动换行显示。
2、在lg和md断点下,封面图片,歌单和常用操作各占一行中显示。

歌单列表

通过List组件的lanes属性实现:在不同断点下,歌单列表的样式一致,但sm和md断点下是歌单列表是单列显示,lg断点下是双列显示,[源码参考]。

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { songList } from '../model/SongList'

import MyDataSource from '../model/SongModule'



@Component

export default struct PlayList {

  @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'

  @StorageProp('fontSize') fontSize: number = 0

  @Consume coverHeight: number



  @Builder

  PlayAll() {

    Row() {

      Image($r("app.media.ic_play_all"))

        .height(23)

        .width(23)

      Text($r('app.string.play_all'))

        .maxLines(1)

        .padding({ left: 10 })

        .fontColor('#000000')

        .fontSize(this.fontSize)

      Blank()

      Image($r('app.media.ic_order_play'))

        .width(24)

        .height(24)

        .margin({ right: 16 })

      Image($r('app.media.ic_sort_list'))

        .height(24)

        .width(24)

    }

    .height(60)

    .width('100%')

    .padding({ left: 12, right: 12 })

  }



  @Builder

  SongItem(title: string, label: Resource, singer: string) {

    Row() {

      Column() {

        Text(title)

          .fontColor('#000000')

          .fontSize(this.fontSize)

          .margin({ bottom: 4 })

        Row() {

          Image(label)

            .width(16)

            .height(16)

            .margin({ right: 4 })

          Text(singer)

            .opacity(0.38)

            .fontColor('#000000')

            .fontSize(this.fontSize - 4)

        }

      }

      .alignItems(HorizontalAlign.Start)



      Blank()

      Image($r('app.media.ic_list_more'))

        .height(24)

        .width(24)

    }

    .height(60)

    .width('100%')

  }



  build() {

    Column() {

      this.PlayAll()

      Scroll() {

        List() {

          LazyForEach(new MyDataSource(songList), item = > {

            ListItem() {

              Column() {

                this.SongItem(item.title, item.label, item.singer)

                Divider()

                  .strokeWidth(0.5)

                  .color('#000')

                  .opacity(0.1)

              }

              .width('100%')

              .height(50)

              .padding({ left: 14, right: 14 })

            }

          }, item = > item.id.toString())

        }

        .width('100%')

        .lanes(this.currentBreakpoint === 'lg' ? 2 : 1)

      }

      .height('100%')

      .flexGrow(1)

      .flexShrink(1)

    }

    .width('100%')

    .height('100%')

    .borderRadius({ topLeft: 20, topRight: 20 })

    .backgroundColor(Color.White)

    .padding({ bottom: this.currentBreakpoint === 'sm' ? this.coverHeight : 0 })

  }

}

播放控制栏

通过Blank组件实现拉伸能力:在不同断点下,播放控制栏显示的内容完全一致,唯一的区别是歌曲信息与播放控制按钮之间的间距有差异。

总体运行效果

通过在首页Column()中引用上述各组件后,可实现首页的组件整合渲染,即可完成整体页面开发,[源码参考]。

/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import { songList } from '../model/SongList'

import MyDataSource from '../model/SongModule'



@Component

export default struct PlayList {

  @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'

  @StorageProp('fontSize') fontSize: number = 0

  @Consume coverHeight: number



  @Builder

  PlayAll() {

    Row() {

      Image($r("app.media.ic_play_all"))

        .height(23)

        .width(23)

      Text($r('app.string.play_all'))

        .maxLines(1)

        .padding({ left: 10 })

        .fontColor('#000000')

        .fontSize(this.fontSize)

      Blank()

      Image($r('app.media.ic_order_play'))

        .width(24)

        .height(24)

        .margin({ right: 16 })

      Image($r('app.media.ic_sort_list'))

        .height(24)

        .width(24)

    }

    .height(60)

    .width('100%')

    .padding({ left: 12, right: 12 })

  }



  @Builder

  SongItem(title: string, label: Resource, singer: string) {

    Row() {

      Column() {

        Text(title)

          .fontColor('#000000')

          .fontSize(this.fontSize)

          .margin({ bottom: 4 })

        Row() {

          Image(label)

            .width(16)

            .height(16)

            .margin({ right: 4 })

          Text(singer)

            .opacity(0.38)

            .fontColor('#000000')

            .fontSize(this.fontSize - 4)

        }

      }

      .alignItems(HorizontalAlign.Start)



      Blank()

      Image($r('app.media.ic_list_more'))

        .height(24)

        .width(24)

    }

    .height(60)

    .width('100%')

  }



  build() {

    Column() {

      this.PlayAll()

      Scroll() {

        List() {

          LazyForEach(new MyDataSource(songList), item = > {

            ListItem() {

              Column() {

                this.SongItem(item.title, item.label, item.singer)

                Divider()

                  .strokeWidth(0.5)

                  .color('#000')

                  .opacity(0.1)

              }

              .width('100%')

              .height(50)

              .padding({ left: 14, right: 14 })

            }

          }, item = > item.id.toString())

        }

        .width('100%')

        .lanes(this.currentBreakpoint === 'lg' ? 2 : 1)

      }

      .height('100%')

      .flexGrow(1)

      .flexShrink(1)

    }

    .width('100%')

    .height('100%')

    .borderRadius({ topLeft: 20, topRight: 20 })

    .backgroundColor(Color.White)

    .padding({ bottom: this.currentBreakpoint === 'sm' ? this.coverHeight : 0 })

  }

}

`HarmonyOSOpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

搜狗高速浏览器截图20240326151450.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 移动开发
    +关注

    关注

    0

    文章

    52

    浏览量

    9686
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2634

    浏览量

    66203
  • HarmonyOS
    +关注

    关注

    79

    文章

    1967

    浏览量

    29997
  • OpenHarmony
    +关注

    关注

    25

    文章

    3657

    浏览量

    16129
  • 鸿蒙OS
    +关注

    关注

    0

    文章

    188

    浏览量

    4367
收藏 人收藏

    评论

    相关推荐

    HarmonyOS开发案例:【一次开发多端部署-音乐专辑

    基于自适应和响应式布局,实现一次开发多端部署音乐专辑页面
    的头像 发表于 05-13 16:48 642次阅读
    HarmonyOS<b class='flag-5'>开发</b>案例:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>-<b class='flag-5'>音乐</b><b class='flag-5'>专辑</b>】

    鸿蒙OS开发:【一次开发多端部署】(多天气)项目

    本示例展示个天气应用界面,包括首页、城市管理、添加城市、更新时间弹窗,体现一次开发多端部署的能力。
    的头像 发表于 05-20 14:59 794次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(<b class='flag-5'>一</b>多天气)项目

    鸿蒙OS开发:【一次开发多端部署】(音乐专辑主页)

    本示例使用一次开发多端部署中介绍的自适应布局能力和响应式布局能力进行多设备(或多窗口尺寸)适配,保证应用在不同设备或不同窗口尺寸下可以正常显示。
    的头像 发表于 05-21 14:48 661次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(<b class='flag-5'>音乐</b><b class='flag-5'>专辑</b>主页)

    鸿蒙OS开发:【一次开发多端部署】(音乐专辑页面

    基于自适应和响应式布局,实现一次开发多端部署音乐专辑页面
    的头像 发表于 05-25 16:21 727次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(<b class='flag-5'>音乐</b><b class='flag-5'>专辑</b><b class='flag-5'>页面</b>)

    鸿蒙OS开发:【一次开发多端部署】(视频应用)

    者提供了“一次开发多端部署”的系统能力,让开发者可以基于一次
    的头像 发表于 05-25 16:29 4470次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(视频应用)

    鸿蒙OS开发:【一次开发多端部署】(典型布局场景

    虽然不同应用的页面千变万化,但对其进行拆分和分析,页面中的很多布局场景是相似的。本小节将介绍如何借助自适应布局、响应式布局以及常见的容器类组件,实现应用中的典型布局
    的头像 发表于 05-25 16:39 2040次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(<b class='flag-5'>典型</b>布局<b class='flag-5'>场景</b>)

    鸿蒙OS开发典型页面场景一次开发多端部署实战(应用市场首页)

    本示例展示了应用市场首页,页面中包括Tab栏、运营横幅、精品应用、精品游戏等。
    的头像 发表于 05-24 15:21 863次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】<b class='flag-5'>实战</b>(应用市场首页)

    鸿蒙OS开发典型页面场景一次开发多端部署实战音乐专辑

    本小节将以音乐专辑为例,介绍如何使用自适应布局能力和响应式布局能力适配不同尺寸窗口。
    的头像 发表于 05-24 20:33 580次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】<b class='flag-5'>实战</b>(<b class='flag-5'>音乐</b><b class='flag-5'>专辑</b><b class='flag-5'>页</b>)

    鸿蒙OS开发典型页面场景一次开发多端部署】(设置应用页面

    本小节以“设置”应用页面为例,介绍如何使用自适应布局能力和响应式布局能力适配不同尺寸窗口。
    的头像 发表于 05-27 10:33 1057次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(设置应用<b class='flag-5'>页面</b>)

    鸿蒙OS开发典型页面场景一次开发多端部署实战(设置典型页面

    本示例展示了设置应用的典型页面,其在小窗口和大窗口有不同的显示效果,体现一次开发多端部署的能力
    的头像 发表于 05-27 09:36 1089次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】<b class='flag-5'>实战</b>(设置<b class='flag-5'>典型</b><b class='flag-5'>页面</b>)

    鸿蒙OS开发典型页面场景一次开发多端部署】(资源使用)

    页面开发过程中,经常需要用到颜色、字体、间距、图片等资源,在不同的设备或配置中,这些资源的值可能不同。
    的头像 发表于 05-28 09:44 906次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(资源使用)

    鸿蒙OS开发典型页面场景一次开发多端部署】(短信)案例介绍

    本章从系统预置的应用中,选择短信应用作为典型的案例,从页面开发和工程结构的角度,介绍"多"的具体实践。系统的产品形态在不断丰富中,当前主要有默认设备和平板两种产品形态,本章的具体实践
    的头像 发表于 05-28 15:08 1175次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(短信)案例介绍

    鸿蒙OS开发:【一次开发多端部署】(多设备自适应能力)简单介绍

    本示例是《一次开发多端部署》的配套示例代码,展示了[页面开发
    的头像 发表于 05-21 14:59 2268次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(多设备自适应能力)简单介绍

    鸿蒙OS开发:【一次开发多端部署】( 设置app页面

    本示例展示了设置应用的典型页面,其在小窗口和大窗口有不同的显示效果,体现一次开发多端部署的能力
    的头像 发表于 05-21 14:56 941次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】( 设置app<b class='flag-5'>页面</b>)

    鸿蒙OS开发典型页面场景一次开发多端部署】(功能开发

    应用开发至少包含两部分工作: UI页面开发和底层功能开发(部分需要联网的应用还会涉及服务端开发)。前面章节介绍了如何解决
    的头像 发表于 05-28 17:32 516次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OS</b><b class='flag-5'>开发</b>:<b class='flag-5'>典型</b><b class='flag-5'>页面</b><b class='flag-5'>场景</b>【<b class='flag-5'>一次</b><b class='flag-5'>开发</b>,<b class='flag-5'>多端</b><b class='flag-5'>部署</b>】(功能<b class='flag-5'>开发</b>)