HarmonyOS实战开发-如何使用首选项能力实现一个简单示例。

介绍

本篇Codelab是基于HarmonyOS的首选项能力实现的一个简单示例。实现如下功能:

  1. 创建首选项数据文件。
  2. 将用户输入的水果名称和数量,写入到首选项数据库。
  3. 读取首选项数据库中的数据。
  4. 删除首选项数据文件。

最终效果图如下:

相关概念

  • 首选项:为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型以及这3种类型的数组类型。
  • TextInput:可以输入单行文本并支持响应输入事件的组件。
  • Button:按钮组件,可快速创建不同样式的按钮。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  • 完成DevEco Device Tool的安装
  • 完成RK3568开发板的烧录

3.搭建开发环境。

  • 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  • 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  • 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets              // 代码区
│  ├──common
│  │  ├──constants
│  │  │  ├──CommonConstants.ets    // 公共常量类
│  │  │  └──StyleConstants.ets     // 样式常量类 
│  │  └──utils
│  │     └──Logger.ets             // 日志打印类
│  ├──entryability
│  │  └──EntryAbility.ts           // 程序入口类
│  ├──model
│  │  └──PreferenceModel.ets       // 首选项相关方法类
│  ├──pages
│  │  └──Index.ets                 // 主界面	
│  ├──view
│  │  ├──ButtonComponent.ets       // 自定义Button组件类
│  │  └──TextItemComponent.ets     // 自定义Text组件类
│  └──viewmodel
│     ├──ButtonItemData.ets        // 按钮数据类
│     └──Fruit.ets                 // 水果数据类
└──entry/src/main/resources        // 资源文件目录

构建主界面

在这个任务中,我们将完成示例主界面的开发,效果图如下:

从上面效果图可以看出,主界面主要由2个相同样式的文本和文本输入框,以及3个相同样式的按钮组成。我们可以将文本和文本输入框抽取成一个TextItemComponent子组件。再将按钮抽取成一个ButtonComponent子组件。

  1. 在ets目录下,点击鼠标右键 > New > Directory,新建名为view的自定义子组件目录。然后在view目录下,点击鼠标右键 > New > ArkTS File,新建两个ArkTS文件,分别为TextItemComponent子组件、ButtonComponent子组件。可以看到文件目录结构如下:

2.文本和文本输入框抽取成的TextItemComponent子组件,效果图如下:

具体代码如下:

// TextItemComponent.ets
@Component
export default struct TextItemComponent {
  private textResource: Resource = $r('app.string.empty'); // 按钮文本资源
  private placeholderResource: Resource = $r('app.string.empty'); // placeholder文本资源
  private marginBottom: string = '';
  private marginTop: string = '';
  private textInputType: InputType = InputType.Normal; // 输入框输入数据类型
  private textFlag: number = 0; // 文本框标记
  @Link fruit: Fruit; // 水果数据
  private textInputCallBack = (value: string) => {}; // TextInput的回调

  build() {
    Column() {
      Text(this.textResource)
        .fontSize(StyleConstants.TEXT_FONT_SIZE)
        .height(StyleConstants.TEXT_HEIGHT)
        .width(StyleConstants.FULL_PERCENT)
        .fontColor($r('app.color.text_font_color'))
        .letterSpacing(StyleConstants.LETTER_SPACING)
        .fontWeight(StyleConstants.FONT_WEIGHT)
        .margin({
          bottom: StyleConstants.TEXT_MARGIN_BOTTOM,
          left: StyleConstants.TEXT_MARGIN_LEFT,
          top: this.marginTop
        })

      TextInput({
        placeholder: this.placeholderResource,
        text: this.textFlag === 0 ? (this.fruit.fruitName) : (this.fruit.fruitNum)
      })
        .placeholderFont({ size: StyleConstants.FONT_SIZE, weight: StyleConstants.FONT_WEIGHT })
        .placeholderColor($r('app.color.placeholder_color'))
        .caretColor(Color.Blue)
        .type(this.textInputType)
        .height(StyleConstants.TEXT_INPUT_HEIGHT)
        .width(StyleConstants.TEXT_INPUT_WIDTH)
        .margin({ bottom: this.marginBottom })
        .fontSize(StyleConstants.FONT_SIZE)
        .fontColor($r('app.color.text_font_color'))
        .fontWeight(StyleConstants.FONT_WEIGHT)
        .backgroundColor($r('app.color.white'))
        .onChange((value: string) => {
          this.textInputCallBack(value);
        })
    }
  }
}

3.抽取的ButtonComponent子组件,效果图如下:

具体代码如下:

// ButtonComponent.ets
@Component
export default struct ButtonComponent {
  private buttonItemValues: Array<ButtonItemData> = this.getButtonItemValues();
  @Link fruit: Fruit; // 水果数据 

  build() {
    Column() {
      ForEach(this.buttonItemValues, (item: ButtonItemData) => {
        Button(item.resource, { type: ButtonType.Capsule, stateEffect: true })
          .backgroundColor($r('app.color.button_background_color'))
          .width(StyleConstants.BUTTON_WIDTH)
          .height(StyleConstants.BUTTON_HEIGHT)
          .fontWeight(StyleConstants.FONT_WEIGHT)
          .fontSize(StyleConstants.FONT_SIZE)
          .margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
          .onClick(() => {
            item.clickMethod();
          })
      }, (item: ButtonItemData) => JSON.stringify(item))
    }
  }
}

4.在Index.ets主界面中引用TextItemComponent和ButtonComponent子组件,具体代码如下:

// Index.ets
Column() {
  // 水果名称输入框
  TextItemComponent({
    textResource: $r('app.string.fruit_text'),
    placeholderResource: $r('app.string.fruit_placeholder'),
    textFlag: CommonConstants.FRUIT_FLAG,
    fruit: $fruit,
    textInputCallBack: (value: string) => {
      this.fruit.fruitName = value;
    }
  })

  // 水果数量输入框
  TextItemComponent({
    textResource: $r('app.string.number_text'),
    placeholderResource: $r('app.string.number_placeholder'),
    textFlag: CommonConstants.NUMBER_FLAG,
    fruit: $fruit,
    textInputCallBack: (value: string) => {
      this.fruit.fruitNum = value;
    }
  })

  // 按钮组件
  ButtonComponent({ fruit: $fruit })
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.main_background_color'))

创建数据文件

创建数据文件需要如下两个步骤:

  • 导入dataPreferences模块。
  • 通过dataPreferences模块的getPreferences(context, name)方法获取到对应文件名的Preferences实例。

Preferences的数据存储在文件中,因此需要指定存储的文件名PREFERENCES_NAME。再通过Preferences提供的方法进行数据库的相关操作。具体代码如下:

// PreferenceModel.ets
// 导入dataPreferences模块
import dataPreferences from '@ohos.data.preferences';

let context = getContext(this);
let preference: dataPreferences.Preferences;
let preferenceTemp: dataPreferences.Preferences;

// 调用getPreferences方法读取指定首选项持久化文件,将数据加载到Preferences实例,用于数据操作
async getPreferencesFromStorage() {
  try {
    preference = await dataPreferences.getPreferences(context, CommonConstants.PREFERENCES_NAME);
  } catch (err) {
    Logger.error(CommonConstants.TAG, `Failed to get preferences, Cause: ${err}`);
  }
}

写入数据

获取Preferences实例后,使用Preferences的put方法,将用户输入的水果名称和水果数量数据,保存到缓存的实例中。再通过Preferences的flush方法将Preferences实例异步存储到首选项持久化文件中。具体代码如下:

// PreferenceModel.ets
async putPreference(fruit: Fruit) {
  ...
  try {
    // 将用户输入的水果名称和水果数量数据,保存到缓存的Preference实例中
    await preference.put(CommonConstants.KEY_NAME, JSON.stringify(fruit));
  } catch (err) {
    Logger.error(CommonConstants.TAG, `Failed to put value, Cause: ${err}`);
  }
  // 将Preference实例存储到首选项持久化文件中
  await preference.flush();
}

读取数据

使用Preferences的get方法读取数据。如果键不存在,则返回默认值。例如获取下面代码中fruit的值,如果fruit的键KEY_NAME不存在,则会返回空字符串。通过默认值的设置,来避免程序出现异常。具体代码如下:

// PreferenceModel.ets
async getPreference() {
  let fruit = '';
  ...
  try {
    fruit = (await preference.get(CommonConstants.KEY_NAME, '')).toString();
  } catch (err) {
    Logger.error(CommonConstants.TAG, `Failed to get value, Cause: ${err}`);
  }
  ...
}

删除数据文件

通过dataPreferences模块的deletePreferences(context, name)方法从内存中移除指定文件对应的Preferences单实例。移除Preferences单实例时,应用不允许再使用该实例进行数据操作,否则会出现数据一致性问题。具体代码如下:

// PreferenceModel.ets
async deletePreferences() {
  try {
    await dataPreferences.deletePreferences(context, CommonConstants.PREFERENCES_NAME);
  } catch(err) {
    Logger.error(CommonConstants.TAG, `Failed to delete preferences, Cause: ${err}`);
  };
  ...
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 如何使用TextInput输入框。
  2. 如何使用首选项数据库。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→HarmonyOS教学视频

HarmonyOS教学视频

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?《鸿蒙基础入门学习指南》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能(Educoder)-- 搜索技术 -- 启发式搜索

任务描述 本关任务&#xff1a;八数码问题是在一个33的棋盘上有1−8位数字随机分布&#xff0c;以及一个空格&#xff0c;与空格相连的棋子可以滑动到空格中&#xff0c;问题的解是通过空格滑动&#xff0c;使得棋盘转化为目标状态&#xff0c;如下图所示。 为了简化问题的输…

简单使用Swagger

文章目录 1、介绍2、 使用步骤3、 常用注解 1、介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(https://swagger.io/)。 它的主要作用是&#xff1a; 使得前后端分离开发更加方便&#xff0c;有利于团队协作 接口的文…

数据可视化-ECharts Html项目实战(6)

在之前的文章中&#xff0c;我们学习了如何设置散点图、雷达图。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢数据可视化-ECharts Html项目实战&#xff08;5&a…

软考96-上午题-【操作系统】-文件目录

一、文件目录 1-1、定义 为了实现“按名存取”&#xff0c;系统必须为每个文件设置用于描述和控制文件的数据结构&#xff0c;它至少要包括&#xff1a;文件名、存放文件的物理地址。 这个数据结构称为&#xff1a;文件控制块(FCB)&#xff0c;文件控制块的有序集合称为文件…

flutter3_douyin:基于flutter3+dart3短视频直播实例|Flutter3.x仿抖音

flutter3-dylive 跨平台仿抖音短视频直播app实战项目。 全新原创基于flutter3.19.2dart3.3.0getx等技术开发仿抖音app实战项目。实现了类似抖音整屏丝滑式上下滑动视频、左右滑动切换页面模块&#xff0c;直播间进场/礼物动效&#xff0c;聊天等模块。 运用技术 编辑器&#x…

Web前端Html的表单

表单的关键字&#xff1a; form标签表示一个表单区域 action“后端地址” method“提交数据方式:get/post” input 单行输入框 type“text” 文本 name“定义名称 名字自定义” 向后端提交的键 readonly“readonly” 只读&#xff0c;不可修改&#xff0c;但是可以提交 disab…

Django 三板斧、静态文件、request方法

【一】三板斧 【1】HttpResponse &#xff08;1&#xff09;介绍 HttpResponse是Django中的一个类&#xff0c;用于构建HTTP响应对象。它允许创建并返回包含特定内容的HTTP响应。 &#xff08;2&#xff09;使用 导入HttpResponse类 from django.http import HttpResponse创…

C++ unordered_set和unordered_map

哈希 1. unordered_set/unordered_map1.1 背景1.2 unordered_set1.2.1 特性1.2.2 常用方法 1.3 unordered_map1.3.1 特性1.3.2 常用方法 2. 哈希2.1概念2.2 哈希冲突2.2.1哈希函数2.2.2 解决哈希冲突2.2.2.1 闭散列2.2.2.2 开散列 1. unordered_set/unordered_map 1.1 背景 之…

Rust并发编程thread多线程和channel消息传递

安全高效的处理并发是 Rust 诞生的目的之一&#xff0c;主要解决的是服务器高负载承受能力。 并发&#xff08;concurrent&#xff09;的概念是指程序不同的部分独立执行&#xff0c;这与并行&#xff08;parallel&#xff09;的概念容易混淆&#xff0c;并行强调的是"同…

如何理解OSI七层模型?

一、是什么 OSI &#xff08;Open System Interconnect&#xff09;模型全称为开放式通信系统互连参考模型&#xff0c;是国际标准化组织 ( ISO ) 提出的一个试图使各种计算机在世界范围内互连为网络的标准框架 OSI将计算机网络体系结构划分为七层&#xff0c;每一层实现各自…

存储随笔原创科普视频首播~

一周之前&#xff0c;存储随笔创建了B站账号。小编利用上个周末休息时间专门研究了B站视频录制的各种方案。发现并没有想象的很容易&#xff0c;先花了很长时间准备了一个PPT&#xff0c;再准备演讲大纲&#xff0c;最终磕磕绊绊完成了首期原创视频录制&#xff01; 可能不尽如…

PCB布线中晶振电容、电源大小电容、电源电容的设计细节

嵌入式软硬件爱好者 一张手册走天下。嵌入式单片机/Linux/Openwrt/电子电路技术交流分享。//主打一个技术层面的剑走偏锋&#xff0c;直击众人重视和不重视的重点//专注基础&#xff0c;才能走的更远 晶振电容 晶振旁边的电容在电路设计中不是用于滤波的。实际上&#xff0c;…

中国疆域从古至今版图演变,中国历史各个朝代地图大全

一、图片描述 每个朝代都有数十张地图&#xff0c;朝代疆域全图重点区域地图&#xff0c;图片是JPG格式&#xff0c;都是高清地图&#xff0c;行政名称清晰可见&#xff0c;非常适合喜欢历史的朋友。本套历史朝代地图&#xff0c;大小1.32G&#xff0c;18个压缩文件。 二、图…

ShardingSphere水平分表——开发经验(2)

1. 什么场景下分表&#xff1f; 数据量过大或者数据库表对应的磁盘文件过大。 Q&#xff1a;多少数据分表&#xff1f; A&#xff1a;网上有人说1kw&#xff0c;2kw&#xff1f;不准确。 1、一般看字段的数量&#xff0c;有没有包含text类型的字段。我们的主表里面是不允许有t…

C语言数据结构之归并排序

疏雨池塘见 微风襟袖知 目录 归并排序的介绍 基本思想 时间复杂度分析 ⭐归并排序步骤 空间复杂度分析 代码展示 ✨归并排序的非递归 代码展示 总结&#x1f525; 归并排序的介绍 归并排序&#xff0c;是创建在归并操作上的一种有效的排序算法。算法是采用分治法&#xff…

项目1-加法计算器

1.创建项目 2.导入前端代码 2.1 static包内 2.2 测试前端代码是否有误 显示成功说明无误 2.3 定义用户接口 请求路径&#xff1a;calc/sum 请求方式&#xff1a;GET/POST 接口描述&#xff1a;计算两个整数相加 请求参数: 参数名类型是否必须备注num1Integer是参与计算的第…

瑞萨杯(一)

基础信息 RA6M5&#xff1a;ARM V8架构&#xff0c;24MHz外置晶振&#xff0c;200MHz主频 SCI&#xff08;Serial Communications Interface&#xff09;&#xff0c;意为串行通信接口 参考链接&#xff1a; 【瑞萨RA系列FSP库开发】RASCKeil的环境搭建_瑞萨ra mdk-CSDN博客…

主干网络篇 | YOLOv8改进之在主干网络中引入密集连接卷积网络DenseNet

前言:Hello大家好,我是小哥谈。DenseNet(密集连接卷积网络)是一种深度学习神经网络架构,它在2017年由Gao Huang等人提出。DenseNet的核心思想是通过密集连接(dense connection)来促进信息的流动和共享。在传统的卷积神经网络中,每个层的输入只来自于前一层的输出。而在…

C语言之strsep用法实例(八十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【Python音视频技术】Python音视频技术系列文章2---视频提取音频转换文字

接上一篇文章 【Python音视频技术】玩AI视频创作引发写Python音视频技术系列文章1---视频添加字幕 之前我想在视频中提取音频转换文字&#xff0c; 当时是用 PC剪映专业版搞定的&#xff0c; 详情见 【AI应用】模仿爆款视频二次创作短视频操作步骤 。 这里我准备用pytho…