鸿蒙5.0项目开发——鸿蒙天气项目的实现(欢迎页)

【高心星出品】

文章目录

      • 欢迎页面效果
      • 数据字典
      • 创建数据库表格
      • Splash页面
        • 页面功能
        • 欢迎页代码
        • 亮点

项目按照从数据库连接层–视图层–业务逻辑层这种三层架构开发,所以先设计了数据库表格的结构,在EntryAbility中创建表格。

欢迎页面效果

在这里插入图片描述

数据字典

  • searchmodel的数据字典:
/***** 搜索历史记录模型*** 用于存储用户搜索关键词的历史记录***/*export interface SearchHistoryItem {id?: number     *// 记录ID,可选*keyword: string   *// 搜索关键词*timestamp?: string  *// 搜索时间戳,可选*}
  • adcode的数据字典:
/***** 城市编码模型*** 用于存储城市相关的编码信息***/*export interface adcode {id: number      *// 城市ID*pid?: number     *// 父级ID,可选*city_code: string  *// 城市编码*city_name: string  *// 城市名称*post_code?: string  *// 邮政编码,可选*area_code?: string  *// 区号,可选*ctime?: string    *// 创建时间,可选*}

这两个模型的主要用途:

SearchHistoryItem:

  • 用于记录用户的搜索历史

  • 包含搜索关键词和时间信息

  • 可用于实现搜索历史功能

adcode:

  • 用于存储城市信息

  • 包含城市编码、名称等基本信息

  • 支持城市层级关系(通过pid)

  • 包含邮政和区号等附加信息

创建数据库表格

编写DbUtils实现对于表格的创建。

  • 创建名为 weatherinfo.db 的数据库

  • 设置数据库安全级别为 S1

  • 初始化两个数据表:

  • t_adcode:存储城市信息

  • t_search:存储搜索历史

import { relationalStore } from "@kit.ArkData";/***作者:gxx*时间:2025/4/21 9:16*功能:数据库操作**/
// 城市编码表名
export const TABLENAME: string = 't_adcode'// 搜索历史表名
export const TABLENAME1: string = 't_search'// 数据库配置
const CONFIG: relationalStore.StoreConfig = {name: 'weatherinfo.db', // 数据库名称securityLevel: relationalStore.SecurityLevel.S1 // 安全级别
}/*** 获取数据库实例* @param context 上下文对象* @returns 数据库实例*/
export async function getrdb(context: Context) {return relationalStore.getRdbStore(context, CONFIG)
}/*** 创建数据库表* @param context 上下文对象* @description 创建城市编码表和搜索历史表*/
export async function createtable(context: Context) {try {// 创建城市编码表SQL语句let sql = 'CREATE TABLE IF NOT EXISTS t_adcode (\n' +'    id INTEGER PRIMARY KEY AUTOINCREMENT,\n' + // 自增主键'name TEXT NOT NULL,    code VARCHAR(50) NOT NULL,\n' + // 城市名称和编码'    city VARCHAR(50) \n' + // 所属城市');'// 创建搜索历史表SQL语句let sql1 = 'CREATE TABLE IF NOT EXISTS t_search (\n' +'  id INTEGER PRIMARY KEY AUTOINCREMENT,\n' + // 自增主键'keyword TEXT NOT NULL,    timestamp VARCHAR(50) NOT NULL);' // 搜索关键词和时间戳// 获取数据库实例并执行SQLlet rdb = await getrdb(context)rdb.executeSync(sql)rdb.executeSync(sql1)} catch (e) {console.error('dbutils 创建表格失败: ', JSON.stringify(e))}
}

在EntryAbility中创建表格。

import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { createtable } from '../utils/Dbutils';const DOMAIN = 0x0000;export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');}onDestroy(): void {hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');}async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {// 1. 记录窗口创建日志hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');// 2. 创建数据库表格// 创建adcode和search_history两个表格用于存储城市代码和搜索历史await createtable(this.context)// 3. 加载启动页面// 加载splash页面,splash页面会检查是否已导入城市数据// 如果未导入则会从cityma.txt读取并导入数据库// 导入完成后跳转到主页面IndexwindowStage.loadContent('pages/splash', async (err) => {if (err.code) {// 4. 加载失败处理hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));return;}// 5. 加载成功记录hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');});}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}onForeground(): void {// Ability has brought to foregroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');}onBackground(): void {// Ability has back to backgroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');}
}

Splash页面

页面功能

1.数据初始化:

  • 页面启动时会检查是否已经加载过城市数据(通过 PreferenceUtils 存储的 isload 标志)

  • 如果数据未加载,会执行 charu 函数来初始化数据

2.charu 函数的具体工作:

  • 从资源文件中读取 cityma.txt(城市码数据文件)

  • 将文件内容解析为 JSON 数据

  • 通过 adcodedao 将城市数据插入到数据库中

  • 使用 @Concurrent 注解确保在后台线程执行,避免阻塞主线程

3.界面展示:

  • 显示一个启动图片

  • 展示一个环形进度条动画

  • 显示"加载中…"文字

4.页面跳转:

  • 数据加载完成后,会自动跳转到主页面(pages/Index)
欢迎页代码
import { adcodedao } from '../dao/adcodedao';
import { buffer, taskpool } from '@kit.ArkTS';
import { common } from '@kit.AbilityKit';
import { adcode } from '../model/adcode';
import { PreferenceUtils } from '../utils/PreferenceUtils';
import { router } from '@kit.ArkUI';/*** 插入城市数据到数据库* @param context 上下文对象* @returns 插入是否成功*/
@Concurrent
async function charu(context: Context) {try {// 创建数据访问对象let ad = new adcodedao(context)// 读取原始文件内容let value = await context.resourceManager.getRawFileContent('cityma.txt')// 转换为字符串let data = buffer.from(value).toString()// 解析JSON数据let content = JSON.parse(data) as adcode[]// 插入数据库await ad.insert(content)return true} catch (e) {console.error('gxxt ', JSON.stringify(e))return false}
}// 持久化存储的key名称
const Prename: string = 'loaded'/*** 启动页面组件*/
@Entry
@Component
struct Splash {@State message: string = 'Hello World';// 进度条值@State value: number = 10// 上下文对象private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext// 定时器IDprivate intervalid: number = 0/*** 组件即将出现时的生命周期函数*/aboutToAppear(): void {// 设置定时器更新进度条this.intervalid = setInterval(() => {if (this.value == 100) {this.value = -10}this.value += 10}, 100)// 检查是否已加载过数据let loaded = PreferenceUtils.getInstance(this.context, Prename).get('isload', false) as booleanif (loaded) {// 如果已加载过数据,直接跳转到主页router.replaceUrl({ url: 'pages/Index' })} else {// 如果未加载过数据,则读取文件并插入数据库taskpool.execute(charu, this.context).then((value) => {// 保存加载状态PreferenceUtils.getInstance(this.context, Prename).putfile('isload', value as boolean)// 跳转到主页router.replaceUrl({ url: 'pages/Index' })})}}/*** 构建UI界面*/build() {Stack() {// 背景图片Image($r('app.media.splash'))// 进度条Progress({ value: this.value, total: 100, type: ProgressType.ScaleRing }).width(100).height(100).backgroundColor(Color.Black).style({ strokeWidth: 15, scaleCount: 20, scaleWidth: 5 }).color(Color.White)// 加载提示文本Text('加载中...').fontWeight(FontWeight.Bolder)}.height('100%').width('100%').alignContent(Alignment.Center)}/*** 组件即将消失时的生命周期函数*/aboutToDisappear(): void {// 清除定时器clearInterval(this.intervalid)}
}
亮点

1.使用多线程将大量数据批量插入数据库

批量插入:

 /*** 批量插入城市数据到数据库* @param acs 城市数据数组* @description 将城市数据批量插入到数据库中* 如果城市数据包含ctime字段,则插入name、code、city三个字段* 否则只插入name和code两个字段*/async insert(acs: adcode[]) {try {// 获取数据库实例let rdb = await getrdb(this.context)// 存储要插入的数据let values: relationalStore.ValuesBucket[] = []// 遍历城市数据acs.forEach((ac: adcode) => {let value: relationalStore.ValuesBucket// 判断是否有ctime字段if (ac.ctime) {value = {'name': ac.city_name, // 城市名称'code': ac.city_code, // 城市编码'city': ac.ctime // 所属城市}} else {value = {'name': ac.city_name, // 城市名称'code': ac.city_code, // 城市编码}}values.push(value)})// 批量插入数据rdb.batchInsertSync(TABLENAME, values)} catch (e) {console.error('gxxt adcodedao 插入数据错误: ', e.message)}}

多线程运行实体:

@Concurrent
async function charu(context: Context) {try {// 创建数据访问对象let ad = new adcodedao(context)// 读取原始文件内容let value = await context.resourceManager.getRawFileContent('cityma.txt')// 转换为字符串let data = buffer.from(value).toString()// 解析JSON数据let content = JSON.parse(data) as adcode[]// 插入数据库await ad.insert(content)return true} catch (e) {console.error('gxxt ', JSON.stringify(e))return false}
}

多线程执行:

 // 如果未加载过数据,则读取文件并插入数据库taskpool.execute(charu, this.context).then((value) => {// 保存加载状态PreferenceUtils.getInstance(this.context, Prename).putfile('isload', value as boolean)// 跳转到主页router.replaceUrl({ url: 'pages/Index' })})

2.使用Interval配合环形刻度进度条来制作动态的加载动画

 // 设置定时器更新进度条this.intervalid = setInterval(() => {if (this.value == 100) {this.value = -10}this.value += 10}, 100)
....................................// 进度条Progress({ value: this.value, total: 100, type: ProgressType.ScaleRing }).width(100).height(100).backgroundColor(Color.Black).style({ strokeWidth: 15, scaleCount: 20, scaleWidth: 5 }).color(Color.White)

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

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

相关文章

使用谱聚类将相似度矩阵分为2类

使用谱聚类将相似度矩阵分为2类的步骤如下&#xff1a; 构建相似度矩阵&#xff1a;提供的1717矩阵已满足对称性且对角线为1。 计算度矩阵&#xff1a;对每一行求和得到各节点的度&#xff0c;形成对角矩阵。 计算归一化拉普拉斯矩阵&#xff1a;采用对称归一化形式 LsymI−D…

MySQL 8.0 OCP 英文题库解析(三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题16~25 试题16:…

【SQL】如何在 SQL 中统计结构化字符串的特征频率

在数据分析场景中&#xff0c;我们经常会遇到需要解析结构化字符串并统计特征出现次数的需求。本文将以常用数据库为例&#xff0c;探讨如何高效处理类似 [特征A][特征B][特征C] 格式的字符串数据&#xff0c;并实现特征频率统计。以下是完整的实现思路和解决方案。 一、问题场…

Docker Compose 的安装方法

以下是 Docker Compose 的安装方法整理&#xff0c;综合了多篇指南的推荐步骤和注意事项&#xff1a; 一、安装前准备 确保已安装 Docker Docker Compose 依赖 Docker 引擎运行&#xff0c;需先安装 Docker。若未安装&#xff0c;可通过以下命令一键安装&#xff08;国内服…

配置Nginx解决http host头攻击漏洞【详细步骤】

前言 大概内容&#xff1a; 安全系统渗透测试出host头攻击漏洞&#xff0c;下面是解决步骤&#xff0c;本人已测过无问题。 server_name aaabbb.com; if ($http_Host !~* ^127.0.0.1|aaabbb.com|localhost$){return 403;}

自研时序大模型讲解(4月29日)直播回顾

4 月 29 日&#xff0c;清华团队揭秘&#xff1a;时序大模型如何让数据“活”起来线上直播圆满结束。清华大学软件学院博士生&#xff0c;IoTDB 原生机器学习引擎 AINode 研发同学刘雍在线上面向数千人次的时序数据分析人员与 AI 大模型行业关注者&#xff0c;就时序大模型的发…

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第二维度,第三维度

attention_weights = torch.ones_like(prompt_embedding[:, :, 0]):切片操作获取第1 维度,第二维度 attention_weights = torch.ones_like(prompt_embedding[:, :, 0]) 这行代码的作用是创建一个与 prompt_embedding[:, :, 0] 形状相同且所有元素都为 1 的张量,它用于初始化…

鸿蒙Next API17新特性学习之如何使用新增鼠标轴事件

今天咱们接着学习鸿蒙开发文档API17版本的新特性——对鼠标轴事件的支持。这对于需要精细交互的应用来说是一个非常有用的特性&#xff0c;例如地图滚动、文档浏览等场景。本文将详细介绍在鸿蒙 Next 中如何使用新增的鼠标轴事件。 开发步骤 环境准备 在开始开发之前&#x…

【行为型之命令模式】游戏开发实战——Unity可撤销系统与高级输入管理的架构秘钥

文章目录 ⌨️ 命令模式&#xff08;Command Pattern&#xff09;深度解析一、模式本质与核心价值二、经典UML结构三、Unity实战代码&#xff08;可撤销的建造系统&#xff09;1. 定义命令接口与接收者2. 实现具体命令3. 命令管理器&#xff08;Invoker&#xff09;4. 客户端使…

计算机网络|| 路由器和交换机的配置

一、实验目的 1. 了解路由器和交换机的工作模式和使用方法&#xff1b; 2. 熟悉 Cisco 网络设备的基本配置命令&#xff1b; 3. 掌握 Cisco 路由器的基本配置方式及配置命令&#xff1b; 4. 掌握路由器和交换机的基本配置与管理方法。 二、实验环境 1. 运行 Windows 操作…

面试--HTML

1.src和href的区别 总结来说&#xff1a; <font style"color:rgb(238, 39, 70);background-color:rgb(249, 241, 219);">src</font>用于替换当前元素&#xff0c;指向的资源会嵌入到文档中&#xff0c;例如脚本、图像、框架等。<font style"co…

CVPR2025 | Prompt-CAM: 让视觉 Transformer 可解释以进行细粒度分析

Prompt-CAM: Making Vision Transformers Interpretable for Fine-Grained Analysis 摘要-Abstract引言-Introduction方法-Approach预备知识-PreliminariesPrompt-CAM: Prompt Class Attention Map特征识别与定位-Trait Identification and Localization变体与扩展-Variants an…

动态规划问题 -- 多状态模型(粉刷房子)

目录 动态规划分析问题五步曲题目概述代码编写 动态规划分析问题五步曲 不清楚动态规划分析问题是哪关键的五步的少年们可以移步到 链接: 动态规划算法基础 这篇文章非常详细的介绍了动态规划算法是如何分析和解决问题的 题目概述 链接: 粉刷房子 状态表示&#xff08;题目要求…

Spring Boot 注解详细解析:解锁高效开发的密钥

一、引言 Spring Boot 以其快速开发、自动配置等特性&#xff0c;成为构建 Java 应用程序的热门框架。而注解在 Spring Boot 中扮演着至关重要的角色&#xff0c;它们如同魔法指令&#xff0c;简化了配置流程&#xff0c;增强了代码的可读性与可维护性。本文将深入剖析 Spring…

【Python】抽象基类ABC

抽象基类(Abstract Base Classes)的核心作用 抽象基类(ABC)是Python中一种特殊的类&#xff0c;它通过abc模块实现&#xff0c;主要服务于面向对象编程中的接口规范和设计约束。以下是它的核心作用&#xff1a; 1. 强制接口实现&#xff08;核心作用&#xff09; 确保子类必…

[python] Python单例模式:__new__与线程安全解析

一 实例的创建过程 我们之前了解过在构造一个类的实例化对象时,会默认调用__init__方法&#xff0c;也就是类的初始化也叫构造函数&#xff0c;但其实在调用__init__方法前会首先调用__new__方法&#xff08;只有在py3新式类才有&#xff09;。即下面 __new__(): 创建实例 作…

笔记本电脑打开网页很慢,一查ip地址网段不对怎么处理

我有一个笔记本&#xff0c;在家里连WIFI后获取到的ip地址网段不对&#xff0c;那么常规做法是手动去配置个静态IP和DNS&#xff0c;要知道笔记本IP地址默认采用的是DHCP&#xff0c;也就是动态获取ip地址。如果手动设置静态IP&#xff0c;也就是固定IP的话&#xff0c;你换个场…

怎样将MM模块常用报表设置为ALV默认格式(MB52、MB5B、ME2M、ME1M等)

【SAP系统研究】 对SAP系统中的报表,最方便的格式就是ALV了,可排序、可导出,非常友好。 但有些常见报表却不是默认ALV界面的,譬如MB52: 是不是有点别扭?但其实是可以后台配置进行调整的。 现将一些常用报表修改为默认ALV的方法进行总结,便于大家使用。 一、MB52、MB5…

Redis——达人探店

达人探店 发布探店笔记 探店笔记类似点评网站的评价&#xff0c;往往是图文结合&#xff0c;对应的表有两个&#xff1a; 发布博文对应两个接口 案例&#xff1a;实现查看发布探店笔记的接口 需求&#xff1a;点击首页的探店笔记&#xff0c;会进入详情页面&#xff0c;实现…

Git初始化相关配置

Git配置 在Git安装完成后&#xff0c;windows操作系统上会多出一个Git Bash的软件&#xff0c;如果是linux或者是macOS&#xff0c;那么直接打开终端&#xff0c;在终端中敲击命令即可 # 检查git版本 git -v # 或 git --version在使用git时&#xff0c;需要配置一下用户名和邮…