【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 })}
}

效果如下所示:

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于STM32的智能语音识别饮水机系统设计

功能描述 1、给饮水机设定称呼&#xff0c;喊出称呼&#xff0c;饮水机回答&#xff1a;我在 2、语音进行加热功能&#xff0c;说&#xff1a;请加热&#xff0c;加热片运行 3、饮水机水位检测&#xff0c;低于阈值播报“水量少&#xff0c;请换水” 4、检测饮水机水温&#xf…

Java 使用MyBatis-Plus数据操作关键字冲突报错You have an error in your SQL syntax问题

问题 这个报错是出现在Java Spring boot项目中&#xff0c;使用MyBatis-Plus通过创建的实体类对数据库的操作过程中&#xff0c;通过实体创建数据库表是没有问题的&#xff0c;而在接口调用服务类操作数据库的时候&#xff0c;会出现报错。报错详情如下&#xff1a; 服务请求异…

高效工具推荐:基于WebGPU的Whisper Web结合内网穿透远程使用指南

文章目录 前言1.本地部署Whisper Web1.1 安装git1.2 安装Node.js1.3 运行项目 2. Whisper Web使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 公网访问测试6. 配置固定公网地址 前言 OpenAI开源的 Whisper 语音转文本模型效果都说还不错&#xff0c;今天就给大家推荐 GitHub…

力扣-Mysql-3322- 英超积分榜排名 III(中等)

一、题目来源 3322. 英超积分榜排名 III - 力扣&#xff08;LeetCode&#xff09; 二、数据表结构 表&#xff1a;SeasonStats --------------------------- | Column Name | Type | --------------------------- | season_id | int | | team_id …

20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况

20241116解决在WIN11和ubuntu20.04通过samba共享时出现局域网千兆带宽拉满的情况 2024/11/16 13:42 缘起&#xff1a;最近需要通过iperf3打流&#xff0c;因此在ubuntu20.04服务器上常开sudo nethogs监控流量。 但是发现一个异常&#xff0c;ubuntu20.04服务器上发送的流量过大…

Stable Diffusion最全提示词写法教程

基础书写规则 所有单词都是通过英文书写&#xff0c;单词之间通过, 分割&#xff0c;注意是英文逗号&#xff1b;提示词之间是可以已通过换行书写的&#xff0c;并不会有什么影响&#xff1b;单个提示词的权重是1 , 默认情况下&#xff0c;越往前&#xff0c;权重越大&#xf…

TON商城与Telegram App:生态融合与去中心化未来的精彩碰撞

随着区块链技术的快速发展&#xff0c;去中心化应用&#xff08;DApp&#xff09;逐渐成为了数字生态的重要组成部分。而Telegram作为全球领先的即时通讯应用&#xff0c;不仅仅满足于传统的社交功能&#xff0c;更在区块链领域大胆探索&#xff0c;推出了基于其去中心化网络的…

Altenergy电力系统 status_zigbee SQL注入漏洞复现(CVE-2024-11305)

0x01 产品描述&#xff1a; Altenergy‌是一家专注于微型逆变器控制软件的公司&#xff0c;Altenergy电力系统控制软件是Altenergy电力系统公司的一款微型逆变器控制软件。 0x02 漏洞描述&#xff1a; Altenergy电力系统 status_zigbee接口处存在SQL注入漏洞&#xff0c;未经身…

3D Streaming 在线互动展示系统:NVIDIA RTX 4090 加速实时渲染行业数字化转型

随着科技的飞速发展&#xff0c;实时渲染正逐步成为游戏与实时交互领域的重要驱动力。与离线渲染不同&#xff0c;实时渲染需要极高的计算性能&#xff0c;对硬件设备尤其是GPU的性能要求极高。随着 RTX 4090 显卡的问世&#xff0c;其强大的算力和创新技术&#xff0c;为实时渲…

【vmware+ubuntu16.04】vm虚拟机及镜像安装-tools安装包弹不出来问题

学习机器人这门课需要下载虚拟机&#xff0c;做一下记录 首先我下载的是vm虚拟机16&#xff0c; 下载版本可参考该文章课堂上我下载 的镜像是16.04&#xff0c;虚拟机安装教程和镜像添加可参考该博主 按照教程安装成功 安装tools&#xff0c;但是我的弹不出来那个压缩包&…

Figma中文网:UI设计师的新资源宝库

Figma作为在线UI设计工具的先驱&#xff0c;已经在全球范围内被广泛使用&#xff0c;尤其是在中国&#xff0c;它已成为众多设计师的首选。本文将揭秘国内顶尖设计师们与Figma搭配使用的神秘伙伴——即时设计资源广场&#xff0c;这个被称为Figma中文网的平台&#xff0c;究竟有…

小试牛刀-Anchor安装和基础测试

目录 一、编写目的 二、安装步骤 2.1 安装Rust 设置rustup镜像 安装Rust 2.2 安装node.js 2.3 安装Solana-CLI 2.4 安装Anchor CLI 三、Program测试 四、可能出现的问题 Welcome to Code Blocks blog 本篇文章主要介绍了 [Anchor安装和基础测试] 博主广交技术好友&…

【后端】版本控制

版本控制 1. 什么是版本控制&#xff1f; 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。简单来说就是用于管理…

CC工具箱使用指南:【CAD导出界址点Excel】

一、简介 群友定制工具。 面图层导出界址点Excel表之前已经做过好几个&#xff0c;这个工具则是将CAD导出Excel。 CAD数据如下&#xff1a; 工具将如上截图中的边界线导出界址点Excel&#xff0c;并记录下面内的文字。 二、工具参数介绍 点击【定制工具】组里的【CAD导出界…

python画图|3D errorbars基础教程

【1】引言 前序学习了errorbar()函数的大部分功能&#xff0c;相关文章包括但不限于下述链接&#xff1a; python画图|errorbar初探_python ax.errorbar-CSDN博客 python画图|errorbar()进阶教程- uplims, lolims和xuplims, xlolims应用_ax.errorbar(x, y 0.5, xerrxerr, y…

RPA真的是人工智能吗?

1. RPA与AI的定义与区别 1.1 RPA的定义与特点 机器人流程自动化&#xff08;Robotic Process Automation&#xff0c;简称RPA&#xff09;是一种软件技术&#xff0c;它通过模拟人类用户的操作行为来自动执行重复性、基于规则的任务。RPA的核心特点包括&#xff1a; 非侵入性…

第23次CCF计算机软件能力认证

1. 数组推导 A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A1​,A2​,⋯,An​ 是一个由 n n n 个自然数&#xff08;即非负整数&#xff09;组成的数组。 在此基础上&#xff0c;我们用数组 B 1 ⋯ B n B_1 \cdots B_n B1​⋯Bn​ 表示 A A A 的前缀最大值。 B i max ⁡ {…

15-大模型 RAG 经验篇

一、LLMs 已经具备了较强能力了&#xff0c;存在哪些不足点? 在 LLM 已经具备了较强能力的基础上&#xff0c;仍然存在以下问题&#xff1a; 幻觉问题&#xff1a;LLM 文本生成的底层原理是基于概率的 token by token 的形式&#xff0c;因此会不可避免地产生"一本正经…

【网络云计算】2024第48周-技能大赛-初赛篇

文章目录 1、比赛前提2、比赛题目2.1、 修改CentOS Stream系统的主机名称&#xff0c;写出至少3种方式&#xff0c;并截图带时间戳和姓名&#xff0c;精确到秒&#xff0c;否则零分2.2、 创建一个名为你的名字的拼音的缩写的新用户并设置密码&#xff0c;将用户名添加到 develo…

C#编写的日志记录组件 - 开源研究系列文章

以前编写过一个日志记录组件的博文&#xff0c;这次发布一个修改过的完善版本。 1、 项目目录&#xff1b; 2、 源码介绍&#xff1b; 1) 实现&#xff1b; 2) 使用&#xff1b; 后面的参数为级别设置&#xff0c;只有大于这个级别的才进行日志记录&#xff0c;限制了日志记录的…