当前位置: 首页 > news >正文

【HarmonyOS】鸿蒙系统在租房项目中的项目实战(一)

        从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?

今天实现一个简单的小案例,从零开始讲解如何通过鸿蒙开发实现一个租房平台的案例。

目录

初始化项目

搭建tabBar

轮播图搭建

主内容搭建


初始化项目

首先我们先打开DevEco Studio,点击新建项目:

然后根据自己的情况选择应用,这里我们选择空的 Empty Ability 进行创建: 

创建完成点击结束之后,我们就可以在pages目录下的index.ets文件中编写代码,如下所示可以看到我们的项目已经成功运行了:

http封装:因为项目肯定是需要用到接口内容的,所以这里我们新建完项目之后需要封装一下请求方法方便后期调用,这里我们可以借助官方给我们提供的第三方仓库网站:地址 如下所示:

然后我们下载我们调用接口的第三方库,终端执行如下命令进行安装: 

ohpm install @ohos/axios

然后我们在ets目录下新建utils工具文件夹,在该文件夹下新建http.ts文件对axios进行二次封装

import axios from '@ohos/axios'
import { promptAction } from '@kit.ArkUI'const http  = axios.create({baseURL: 'http://192.168.0.110:6060', // 请求地址timeout: 5000,
})http.interceptors.request.use((config) => {// 后期可以添加校验token内容return config},(error) => {promptAction.showToast(error.message) // 错误提示return Promise.reject(error)},
)http.interceptors.response.use((response) => {if (response.data.code === 200) {return response.data} else {promptAction.showToast(response.data.message) // 错误提示return Promise.reject(response.data.message)}},(error) => {promptAction.showToast(error.message) // 错误提示return Promise.reject(error)},
)
export default http

封装好接口之后,接下来我们需要配置下网络权限,方便后期我们使用真机模拟器的时候,网络服务是能够正常去请求的,如下所示:

在开发项目的时候,接口可能很多需要统一管理,我们直接在ets目录下去创建api文件夹去统一管理项目的接口: 

import http from "../../utils/http"
import type { HomeData } from './type'// 统一管理接口
enum API {HOME_INFO = '/home/info',
}// 获取首页数据
export const reqHomeData = () =>http.get<any, HomeData>(API.HOME_INFO)

搭建tabBar

        接下来我们开始搭建我们的tabBar内容,这里我们使用官方文档提供的Tabs组件进行搭建,这里我们先创建五个ets文件代表五个要实现的五个tab界面,首先我们先准备好tab切换的图片资源,资源可以在阿里云图标库上进行寻找,这里不再赘述,找到对应的这种放置在b资源文件base下的media目录里面:

然后我们通过构建器创建一个tab函数,里面实现的是图片和文本,根据用户点击不同的tab然后进行样式的切换,代码如下:

import Home from "./Home"
import See from "./See"
import Service from "./Service"
import Discover from "./Discover"
import My from "./My"@Entry
@Component
struct Index {@State currentTabBarIndex: number = 0@Builder tabBarBuilder(image: Resource, activeImage: Resource, text: string, index: number) {Column() {Image(this.currentTabBarIndex === index ? activeImage : image).width(28).height(28 )Text(text).fontSize(10).fontColor(this.currentTabBarIndex === index ? '#000' : '#A0A0A0')}}build() {Tabs({ barPosition: BarPosition.End }) {TabContent() {Home()}.tabBar(this.tabBarBuilder($r('app.media.tabbar_home'), $r('app.media.tabbar_home_active'), '首页', 0))TabContent() {See()}.tabBar(this.tabBarBuilder($r('app.media.tabbar_see'), $r('app.media.tabbar_see_active'), '想看', 1))TabContent() {Service()}.tabBar(this.tabBarBuilder($r('app.media.tabbar_service'), $r('app.media.tabbar_service_active'), '服务', 2))TabContent() {Discover()}.tabBar(this.tabBarBuilder($r('app.media.tabbar_discover'), $r('app.media.tabbar_discover_active'), '发现', 3))TabContent() {My()}.tabBar(this.tabBarBuilder($r('app.media.tabbar_my'), $r('app.media.tabbar_my_active'), '我的', 4))}.barHeight(50).scrollable(false).onChange((index: number) => {this.currentTabBarIndex = index})}
}

最终呈现的效果如下所示:

因为项目中可能许多地方会使用相同的变量,例如文字颜色或者大小等等,这里我们设置一下全局公共的样式内容,如下所示:

然后我们回到刚才我们设置tab的颜色的位置,设置成我们定义的全局公共样式:

当然我们也可以设置一下公共的常量内容,类似整个页面布局的边距,阴影圆角等等,这里我们直接在ets文件夹下新建一个资源目录,用于存放我们的定义的常量内容,方便后期用到:

轮播图搭建

首页的内容有很多,这里我们简单的讲每个模块用到的内容都讲解一下在home页面,我们通过Scroll组件来排列模块内容,首先我们先实现轮播图组件,这里我们将轮播图组件抽离出去,然后通过props将接口当中的数据传递给组件:

import { reqHomeData } from '../api/home'
import type { HomeData, bannerList } from '../api/home/type'
import SwiperLayout from '../components/Home/SwiperLayout'@Component
export default struct Home {@State bannerList: bannerList[] = []// 获取首页数据getHomeData = async () => {const res: HomeData = await reqHomeData()this.bannerList = res.data.bannerList}// 初始化页面调用aboutToAppear(): void {this.getHomeData()}build() {Scroll() {Column() {// 轮播图组件使用props通信SwiperLayout({ bannerList: this.bannerList })}.width('100%')}.width('100%').height('100%').scrollBar(BarState.Off).align(Alignment.TopStart)}
}

在轮播图组件当中,我们调用轮播组件Swiper,通过ForEach循环渲染图片资源,然后轮播组件设置对应的轮播参数内容即可,代码如下所示:

import type { bannerList } from '../../api/home/type'@Component
export default struct SwiperLayout {@Prop bannerList: bannerList[];build() {Swiper() {ForEach(this.bannerList, (item: bannerList) => {Image(item.imageURL).width('100%').height('100%').objectFit(ImageFit.Fill)}, (banner: bannerList) => banner.id.toString())}.width('100%').height(211 -36) // 减去状态栏高度36.autoPlay(true).interval(3000).indicator(new DotIndicator().color($r('app.color.indicator_color')).selectedColor($r('app.color.indicator_color_active')))}
}

去除上下留白:因为新版本的鸿蒙预览器是有安全距离的,也就是说手机预览器上下会有一定的空间留白,如果想清除这些留白的话在index.ets根文件中调用如下函数即可:

import { window } from '@kit.ArkUI';onPageShow(): void {window.getLastWindow(AppStorage.get("context"), (err, data) => {if (err.code) {console.error('Failed to get last window. Cause:' + JSON.stringify(err));return;}data.setWindowLayoutFullScreen(true)});
}

最终呈现的效果如下所示:

主内容搭建

搜索栏搭建:内容很简单,我们借助层叠组件Stack在轮播图组件上搭建一个搜索栏组件,如下所示:

然后也是借助层叠组件,调整一下样式即可,然后把静态的搜索栏搭建出来:

import { PADDING, PADDING_S } from '../../contants/size'@Component
export default struct SearchBar {build() {Row({ space: PADDING }) {Text('北京').fontSize(14).fontColor($r('app.color.white'))Stack() {TextInput().width(244).height('100%').backgroundColor($r('app.color.white'))Row() {Image($r('app.media.search')).width(18).height(18)Text('公司/地铁/小区,马上搜索').fontSize(10).fontColor($r('app.color.gray')).layoutWeight(1).margin({ left: PADDING_S, right: PADDING_S })Column() {}.width(1).height(18).backgroundColor($r('app.color.line')).margin({ right: PADDING })Image($r('app.media.position')).width(18).height(18)}.width('100%').padding({ left: PADDING, right: PADDING })}.width(244)Image($r('app.media.message')).width(24).height(24).fillColor($r('app.color.white'))}.width('100%').height(38).padding({ left: PADDING, right: PADDING }).margin({ top: 4 })}
}

最终呈现的效果如下所示:

导航栏搭建:导航栏的内容这里我们就使用Grid布局进行处理,首先我们先定义导航栏组件然后在Home文件中进行引入,然后将首页的接口函数data中的数值赋值给navList,然后通过props的方式传递给导航栏组件,如下所示:

然后我们来到导航栏组件,通过Grid布局并调整相应的样式即可:

import { navList } from '../../api/home/type'@Component
export default struct NavList {@Prop navList: navList[]build() {Grid() {ForEach(this.navList, (item: navList) => {GridItem() {Column({ space: 8 }) {Image(item.imageURL).width(58).height(56).objectFit(ImageFit.Fill)Text(item.title).fontSize(12).fontColor($r('app.color.black'))}}}, (nav: navList) => nav.id.toString())}.width('100%').height(170).rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr 1fr').rowsGap(14).columnsGap(32).margin({ top: 24 })}
}

最终呈现的效果如下所示:

标题栏搭建:接下来开始对标题栏中的内容进行书写,老样子我们需要先定义标题栏组件,然后在Home文件中进行引入,并将首页数据data当中的titleList通过props通信传递给标题栏组件:

然后这里就很简单了,通过ForEach的方式进行渲染数据即可:

import { tileList } from '../../api/home/type'@Component
export default struct TitleList {@Prop titleList: tileList[]build() {Row({ space:32 }) {ForEach(this.titleList, (item: tileList) => {Column({ space: 8 }) {Image(item.imageURL).width('100%').height(58).objectFit(ImageFit.Fill)Row({ space: 5 }) {Text(item.title).fontSize(12).fontColor($r('app.color.black'))Text(item.sub_title).fontSize(10).fontColor($r('app.color.gray'))}.width('100%')}.width(148)}, (tit: tileList) => tit.id.toString())}.width('100%').margin({ top: 12 })}
}

最终呈现的效果如下所示:

列表栏搭建:同理列表栏搭建的方式和上面一样,这里就直接给出代码了:

import { planList } from '../../api/home/type'@Component
export default struct PlanList {@Prop planList: planList[]build() {Row({ space: 5 }) {ForEach(this.planList, (item: planList) => {Image(item.imageURL).width(78).height(60).objectFit(ImageFit.Fill)}, (plan: planList) => plan.id.toString())}.width('100%').margin({ top: 18 })}
}

效果如下所示:

下面的内容就放置一个广告图,代码很简单,这里就不再赘述了:

相关文章:

【HarmonyOS】鸿蒙系统在租房项目中的项目实战(一)

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…...

前 K 个高频元素

前 K 个高频元素 ​ 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: [1]提示&#xff1a; 1 < nums.le…...

【ubuntu】Geogebra

Geogebra 几何作图工具 是一款跨平台的几何作图工具软件&#xff0c; 目前已经覆盖了&#xff0c; windows&#xff0c;android&#xff0c; mac, linux 等操作系统。 Ubuntu 现状 Ubuntu 自带应用市场 Ubuntu 自带应用市场目前只有 Geogebra 4.0 版本&#xff0c; 不能画立…...

vue2和vue3的区别详解

vue2 VS vue3 对比vue2vue3配置脚手架cmd命令行可视化方式创建脚⼿架组件通信props、$emit、provide、$arrts、EventBus等props、$emit、provide、inject、arrts等数据监听watch,computedwatch,watchEffect,computed双向绑定Object.definePropertyProxyAPI⽣命周期四个阶段befo…...

一文读懂LEED绿建

LEED绿建&#xff0c;即获得LEED&#xff08;Leadership in Energy and Environmental Design&#xff09;认证的建筑&#xff0c;是一个旨在提高建筑环境性能和健康性能的评估体系。以下是对LEED绿建的详细解读&#xff1a; 一、LEED体系概述 定义&#xff1a;LEED是由美国绿…...

git上feature合并到development分支

git上从development分支拉了一个feature分支开发新内容&#xff0c;development也有新内容在开发&#xff0c;feature分支内容开发完毕后&#xff0c;如何合并feature分支新内容到development分支&#xff0c;要确保不会覆盖development分支的新内容 以下是将 feature 分支的新…...

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备:大华IPC摄像头局域网访问异常解决办法

在当今社会&#xff0c;安全监控已成为各类场所不可或缺的一部分。无论是家庭、学校、商业场所还是公共场所&#xff0c;安全监控设备都扮演着至关重要的角色。在众多监控品牌中&#xff0c;大华IPC摄像头凭借其高清画质、强大功能和卓越稳定性&#xff0c;赢得了市场的广泛认可…...

校园二手交易网站毕业设计基于SpringBootSSM框架

目录 一、引言 二、需求分析 2.1用户需求分析 2.1.1学生用户 2.1.2管理员 2.2系统功能需求 2.3系统非功能需求 ‌2.4技术需求 ‌2.4.1 技术选择 ‌2.4.2系统架构‌ 三、详细设计 3.1系统架构设计‌ ‌3.2前端设计‌ ‌3.3后端设计‌ ‌3.4数据库设计‌ 本文介绍…...

基于大语言模型意图识别和实体提取功能;具体ZK数值例子:加密货币交易验证;

目录 基于大语言模型意图识别和实体提取功能 案例背景 零知识证明过程 具体例子 具体举例(简化) 具体ZK数值例子:加密货币交易验证 定义多项式 承诺 挑战 证明构造 证明验证 结论 zkLLM Zero Knowledge Proofs for Large Language Models 在大模型验证过程中处…...

论文笔记 SuDORMRF:EFFICIENT NETWORKS FOR UNIVERSAL AUDIO SOURCE SEPARATION

SUDORMRF: EFFICIENT NETWORKS FOR UNIVERSAL AUDIO SOURCE SEPARATION 人的精神寄托可以是音乐&#xff0c;可以是书籍&#xff0c;可以是运动&#xff0c;可以是工作&#xff0c;可以是山川湖海&#xff0c;唯独不可以是人。 Depthwise Separable Convolution 深度分离卷积&a…...

机器学习系列----KNN分类

目录 前言 一.KNN算法的基本原理 二.KNN分类的实现 三.总结 前言 在机器学习领域&#xff0c;K近邻算法&#xff08;K-Nearest Neighbors, KNN&#xff09;是一种非常直观且常用的分类算法。它是一种基于实例的学习方法&#xff0c;也被称为懒学习&#xff08;Lazy Learnin…...

贪心算法day 06

1.最长回文串 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;计算每个字符个数如果是偶数个那么肯定可以组成回文串&#xff0c;如果是奇数个就会有一个无法组成回文串&#xff0c;但是在最中间还是可以有一个不是成队的字符这个字符就从多的奇…...

HTML之列表学习记录

练习题&#xff1a; 图所示为一个问卷调查网页&#xff0c;请制作出来。要求&#xff1a;大标题用h1标签&#xff1b;小题目用h3标签&#xff1b;前两个问题使用有序列表&#xff1b;最后一个问题使用无序列表。 代码&#xff1a; <!DOCTYPE html> <html> <he…...

Redo与Undo的区别:数据库事务的恢复与撤销机制

在数据库中&#xff0c;redo 和 undo 是两个非常重要的概念&#xff0c;它们主要用于事务管理和恢复机制&#xff0c;确保数据的一致性和完整性。 下面分别解释这两个概念&#xff1a; Redo&#xff08;重做&#xff09; 定义&#xff1a;redo 操作记录了事务对数据库所做的所…...

【话题讨论】AI赋能电商:创新应用与销售效率的双轮驱动

目录 引言 一、AI技术在电商中的创新应用 1.1 购物推荐 1.2 会员分类 1.3 商品定价 1.4 用户体验 总结 二、AI技术提高电商平台销售效率 2.1 订单处理 2.2 物流配送 2.3 产品流转效率 2.4 库存管理和订单管理效率 2.5 实际案例分析 三、挑战和未来发展趋势 3.1…...

重构开发之道,Blackbox.AI为技术注入智能新动力

本文目录 一、引言二、Blackbox.AI实战体验2.1 基于网页界面生成前端代码进行应用开发2.2 与AI助手实现实时智能对话2.3 重塑大型文件交互方式2.4 链接Github仓库进行对话编程 三、总结 一、引言 在生产力工具加速进化的浪潮中&#xff0c;Blackbox.AI开始崭露头角&#xff0c…...

机器学习在医疗健康领域的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 机器学习在医疗健康领域的应用 机器学习在医疗健康领域的应用 机器学习在医疗健康领域的应用 引言 机器学习概述 定义与原理 发展…...

M芯片Mac构建Dockerfile - 注意事项

由于MacBook的M芯片架构与intel不同&#xff0c;交叉构建Linux服务器docker镜像&#xff0c;需要以下步骤完成&#xff1a; 编写好Dockerfile在命令行中&#xff0c;执行构建命令&#xff1a; docker buildx build --platform linux/amd64 -t ${image_name}:${tag} ....

系统架构设计师论文

软考官网&#xff1a;中国计算机技术职业资格网 (ruankao.org.cn) 2019年 2019年下半年试题二&#xff1a;论软件系统架构评估及其应用...

速盾:CDN 和高防有什么区别?

在网络安全和性能优化领域&#xff0c;CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;和高防服务是两个重要的概念&#xff0c;它们在功能、原理和应用场景方面存在诸多区别。 一、CDN &#xff08;一&#xff09;基本原理与功能 内容加速分发…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...