鸿蒙OS开发:【一次开发,多端部署】(app市场首页)项目

news2024/11/26 6:56:27

一多应用市场首页

介绍

本示例展示了应用市场首页,页面中包括Tab栏、运营横幅、精品应用、精品游戏等。

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

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

效果预览

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

image.png

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

image.png

使用说明:

  1. 启动应用,可以查看本应用在全屏状态下的显示效果。
  2. 在应用顶部,下滑出现窗口操作按钮。(建议通过外接鼠标操作,接入鼠标只需要将鼠标移动至顶部即可出现窗口)
  3. 点击悬浮图标,将应用悬浮在其它界面上显示。
  4. 拖动应用悬浮窗口的边框,改变窗口尺寸,触发应用刷新,即可查看应用在不同窗口下的显示效果。
  5. 改变窗口尺寸的过程中,窗口尺寸可能超出屏幕尺寸。此时在屏幕中只能看到应用部分区域的显示,但可以通过移动窗口位置,查看应用其它区域的显示。
  6. 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

工程目录

AppMarket/entry/src/main/ets/
|---model
|   |---HomeData.ets                       // 主页用到的图片资源
|   |---HomeDataType.ets                   // 事件监听函数
|---pages                                  
|   |---index.ets                          // 首页
|---common                                    
|   |---BreakpointSystem.ets               // 媒体查询
|   |---Home.ets                           // 主容器
|   |---IndexApps.ets                      // app模块(包含安装,展示图片,更多功能)
|   |---IndexContent.ets                   // 内容模块
|   |---IndexEntrance.ets                  // 下一步模块(箭头跳转组件)
|   |---IndexHeader.ets                    // 头部组件
|   |---IndexSwiper.ets                    // 轮播图   
|   |---TabBarItem.ets                     // 导航栏                                            

具体实现

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

底部/侧边导航栏

1、在sm和md断点下,导航栏在底部;在lg断点下,导航栏在左侧。
2、通过Tab组件的barPosition和vertical属性控制TabBar的位置在主轴方向起始或结尾位置和水平或垂直方向,同时还可以通过barWidth和barHeight属性控制TabBar的尺寸,[源码参考]。

/*

 * Copyright (c) 2022 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 Home from '../common/Home'

import TabBarItem from '../common/TabBarItem'

import BreakpointSystem from '../common/BreakpointSystem'



@Entry

@Component

struct Index {

  @State currentIndex: number = 0

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

  private breakpointSystem: BreakpointSystem = new BreakpointSystem()

  private onTabChange = (index: number) => {

    this.currentIndex = index

  }



  aboutToAppear() {

    this.breakpointSystem.register()

  }



  aboutToDisappear() {

    this.breakpointSystem.unregister()

  }



  @Builder

  tabItem(index: number, title: Resource, icon: Resource, iconSelected: Resource) {

    TabBarItem({

      index: index,

      currentIndex: this.currentIndex,

      title: title,

      icon: icon,

      iconSelected: iconSelected

    })

  }



  build() {

    Tabs({ barPosition: this.currentBreakpoint === 'lg' ? BarPosition.Start : BarPosition.End }) {

      TabContent() {

        Home()

      }

      .tabBar(this.tabItem(0, $r('app.string.tabBar1'), $r('app.media.ic_home_normal'), $r('app.media.ic_home_actived')))



      TabContent() {

      }

      .tabBar(this.tabItem(1, $r('app.string.tabBar2'), $r('app.media.ic_app_normal'), $r('app.media.ic_app_actived')))



      TabContent() {

      }

      .tabBar(this.tabItem(2, $r('app.string.tabBar3'), $r('app.media.ic_game_normal'), $r('app.media.ic_mine_actived')))



      TabContent() {

      }

      .tabBar(this.tabItem(3, $r('app.string.tabBar4'), $r('app.media.ic_search_normal'), $r('app.media.ic_search_actived')))



      TabContent() {

      }

      .tabBar(this.tabItem(4, $r('app.string.tabBar4'), $r('app.media.ic_mine_normal'), $r('app.media.ic_mine_actived')))

    }

    .barWidth(this.currentBreakpoint === 'lg' ? 96 : '100%')

    .barHeight(this.currentBreakpoint === 'lg' ? '60%' : 56)

    .vertical(this.currentBreakpoint === 'lg')

    .onChange(this.onTabChange)

    .backgroundColor('#F1F3F5')

  }

}
标题栏与搜索栏

通过栅格实现标题栏和搜索栏:在sm和md断点下分两行显示,在lg断点下单行显示,[源码参考]。

/*

 * Copyright (c) 2022 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.

 */



@Component

export default struct IndexHeader {

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



  @Builder searchBar() {

    Stack({alignContent: Alignment.End}) {

      TextInput({ placeholder: $r('app.string.search') })

        .placeholderColor('#FF000000')

        .placeholderFont({ size: 16, weight: 400 })

        .textAlign(TextAlign.Start)

        .caretColor('#FF000000')

        .width('100%')

        .height(40)

        .fontWeight(400)

        .padding({ top: 9, bottom: 9 })

        .fontSize(16)

        .backgroundColor(Color.White)



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

        .width(16)

        .height(16)

        .margin({ right: 20 })

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

  }



  @Builder titleBar() {

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

      .fontSize(24)

      .fontWeight(500)

      .fontColor('#18181A')

      .textAlign(TextAlign.Start)

      .height(56)

      .width('100%')

  }



  build() {

    GridRow() {

      GridCol({ span: { xs: 12, lg: 8 } }) {

        this.titleBar()

      }

      GridCol({ span: { xs: 12, lg: 4 } }) {

        this.searchBar()

      }

    }

    .width('100%')

    .height(this.currentBreakpoint === 'lg' ? 56 : 112)

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

  }

}

2、在sm和md断点下,标题栏和搜索栏占满12列,此时会自动换行显示。
3、在lg断点下,标题栏占8列而搜索栏占4列,此时标题栏和搜索栏在同一行中显示。

运营横幅

实现不同断点下的运营横幅:通过Swiper组件的displayCount属性,sm断点下显示一张图片,md断点下显示两张图片,lg断点下显示三张图片。

快捷入口

通过将justifyContent参数配置为FlexAlign.SpaceEvenly实现均分布局:在不同的断点下,快捷入口的5个图标始终均匀排布。

精品应用

通过List组件能力,实现延伸能力场景:随着可用显示区域的增加,精品应用中显示的图标数量也不断增加,[源码参考]。

/*

 * 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 { AppItem, MyAppSource } from '../model/HomeDataType'



@Component

export default struct IndexApps {

  private title: Resource

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

  private apps: AppItem[] = []



  @Builder

  appListHeader() {

    Row() {

      Text(this.title)

        .width(100)

        .fontSize(16)

        .textAlign(TextAlign.Start)

        .fontWeight(500)

      Blank()

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

        .fontSize(14)

        .textAlign(TextAlign.End)

        .fontWeight(400)

        .margin({ right: 2 })

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

        .width(12)

        .height(18)

        .opacity(0.9)

        .objectFit(ImageFit.Fill)

    }

    .margin({ bottom: 9, top: 9 })

    .width('100%')

    .alignItems(VerticalAlign.Bottom)

  }



  @Builder

  appListItem(app:AppItem) {

    Column() {

      Image(app.image)

        .width(this.currentBreakpoint === 'lg' ? 80 : 56)

        .height(this.currentBreakpoint === 'lg' ? 80 : 56)

        .margin({ bottom: 8 })

      Text(app.title)

        .width(this.currentBreakpoint === 'lg' ? 80 : 56)

        .height(16)

        .fontSize(12)

        .textAlign(TextAlign.Center)

        .fontColor('#18181A')

        .margin({ bottom: 8 })

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

        .width(this.currentBreakpoint === 'lg' ? 80 : 56)

        .height(28)

        .fontColor('#0A59F7')

        .textAlign(TextAlign.Center)

        .borderRadius(this.currentBreakpoint === 'lg' ? 26 : 20)

        .fontWeight(500)

        .fontSize(12)

        .padding({ top: 6, bottom: 6, left: 8, right: 8 })

        .backgroundColor('rgba(0,0,0,0.05)')

    }

  }





  build() {

    Column() {

      this.appListHeader()

      List({ space: this.currentBreakpoint === 'lg' ? 44 : 20}) {

        LazyForEach(new MyAppSource(this.apps), app => {

          ListItem() {

            this.appListItem(app)

          }

        }, app => app.id)

      }

      .width('100%')

      .height(this.currentBreakpoint === 'lg' ? 140 : 120)

      .listDirection(Axis.Horizontal)

    }

    .width('100%')

    .height(this.currentBreakpoint === 'lg' ? 188 : 164)

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

  }

}

`HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

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

总体运行效果

通过将上述各页面在List() {}中引用组件后,可实现首页的组件整合渲染,即可完成整体页面开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1708916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【pyspark速成专家】11_Spark性能调优方法2

目录 ​编辑 二,Spark任务UI监控 三,Spark调优案例 二,Spark任务UI监控 Spark任务启动后,可以在浏览器中输入 http://localhost:4040/ 进入到spark web UI 监控界面。 该界面中可以从多个维度以直观的方式非常细粒度地查看Spa…

大数据技术Hbase列数据库——topic1

目录 搭建单机版Hbase验证方法一验证方法二 搭建单机版Hbase 验证方法一 使用 jps 命令查看 HMaster 进程是否启动 首先使用xftp 7上传hbase-2.1.0安装压缩包到虚拟机进行解压缩到某一地址,这里解压缩到了上传的路径即/root/software/ tar -zxvf hbase-2.1.0-bi…

OrangePi AIpro (8T)使用体验,性能测试报告

前言 这段时间收到了CSDN和香橙派的邀请,对OrangePi AIpro进行体验测评,在此感谢CSDN对我的信任,也感谢香橙派能做出如此优秀的开发板。 可喜可贺,周三晚上我收到了官方寄出的OrangePi AIpro。出于对国产芯片的好奇&#xff0c…

苹果与OpenAI合作在即:iOS 18中的ChatGPT引发期待与担忧

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

idea的project structure下project [lauguage ]()level 没有java的sdk17选项如何导入

idea的project structure下project lauguage level 没有java的sdk17选项如何导入 别导入了,需要升级idea版本。idea中没有project language level没有17如何添加 - CSDN文库 别听这文章瞎扯淡 2021版本就是没有,直接卸载升级到最新版本就可以了。没办法…

马斯克的 xAI 帝国!60亿融资背后的超级布局?

在全球科技竞技场,每个重大融资事件都是对行业格局的一次重塑。近日,埃隆马斯克的人工智能初创企业 xAI 成功完成了一轮规模空前的融资——60亿美元,此举无疑在业界投下了一枚震撼弹,标志着 AI 领域内一场新的竞赛拉开了序幕。 …

SwiftUI中AppStorage的介绍使用

在Swift中,AppStorage是SwiftUI中引入的一个属性包装器,在这之前我们要存储一些轻量级的数据采用UserDefaults进行存取。而AppStorage用于从UserDefaults中读取值,当值改变时,它会自动重新调用视图的body属性。也就是说&#xff0…

CC1310 Debug interface is locked

XDS110连接CC1310板子,打开Smart RF 弹出窗口如下: 解决办法: 1 打开SmartRF Flash Programmer 2 选择连接的设备CC1310, 弹出如下窗口,点击OK。 3 点击Tools图标,选择CC26XX/CC13XX Forced Mass Erase。 4 在弹出的…

骆驼大赛

目录 一,主版图 二,骰子 三,初始设置 四,核心规则 五,结算 这是适合5-8人玩的一个概率推理类的回合制桌游。 一,主版图 赛道由16个格子组成,编号为1-16。 一共7个骆驼,其中正…

就说说Java初学者求职准备项目的正确方式

当下不少Java初学者也知道求职时项目的重要程度,但在简历上写项目和准备面试项目时,真有可能走弯路,这样的话,加重学习负担还是小事,还真有可能导致无法入职。 1 对于在校生和应届生来说,你去跑通个学习项…

四川汇聚荣聚荣科技有限公司好不好?

在当今科技飞速发展的时代,企业要想在激烈的市场竞争中脱颖而出,必须具备强大的技术实力和良好的市场口碑。那么,作为一家专注于科技创新的公司,四川汇聚荣聚荣科技有限公司究竟如何呢?接下来,我们将从四个方面进行详…

探索Python列表的奥秘:从零开始学习

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、列表简介与用途 二、列表的创建与访问 三、列表的增删改查 四、列表生成式与高级操作…

信创加持 YashanDB通过商用密码产品认证

近期,深算院自主研发的“YashanDB V23”成功获得由国家密码管理局商用密码检测中心颁发的《商用密码产品认证证书》,通过GM/T 0028《密码模块安全技术要求》安全等级第二级认证。这标志着YashanDB密码技术和密码管理领域达到了国家标准,能够全…

股民用脚投票 退退退!

倒计时2天,看来今年首只非ST类要退市的股票诞生了。 继上周五封S跌停后,今天正源(股份)再度被股民用脚投票一字跌停, 这已经连续第18个交易日股价低于1块钱了。 按照退市新规,连续20个交易日股价低于1元是…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(九)

本系列课程,将重点讲解Phpsploit-Framework框架软件的基础使用! 本文章仅提供学习,切勿将其用于不法手段! 继续接上一篇文章内容,讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 现在,我们…

信息标记形式 (XML, JSON, YAML)

文章目录 🖥️介绍🖥️三种形式🏷️XML (Extensible Markup Language)🔖规范🔖注释🔖举例🔖其他 🏷️JSON (JavaScript Object Notation)🔖规范🔖注释&#x…

机器之心 | 清华接手,YOLOv10问世:性能大幅提升,登上GitHub热榜

本文来源公众号“机器之心”,仅用于学术分享,侵权删,干货满满。 原文链接:清华接手,YOLOv10问世:性能大幅提升,登上GitHub热榜 相同性能情况下,延迟减少 46%,参数减少 2…

知识产权与标准化

知识产权与标准化 导航 文章目录 知识产权与标准化导航一、知识产权概述二、保护范围与对象三、保护期限四、知识产权归属五、侵权判定六、标准的分类 一、知识产权概述 知识产权:知识产权是指人们就其智力劳动成果所依法享有的专有权利,通常是国家赋予创造者对其…

SNP数据转型解析:云服务在现代企业数字化转型的必要性

为什么当今的企业想为数字化工作环境做好准备并保持竞争力,很难避免使用云服务呢? 要理解为什么企业没有云的替代选择,我们需要了解云服务的含义 - 它不仅仅指存储数据的另一个位置。各种云模型提供了极大的灵活性,可以根据需要操…

149.二叉树:二叉树的前序遍历(力扣)

代码解决 这段代码实现了二叉树的前序遍历,前序遍历的顺序是:访问根节点 -> 递归遍历左子树 -> 递归遍历右子树。以下是详细解释,包括各个部分的注释: // 二叉树节点的定义 struct TreeNode {int val; // 节…