介紹
用戶首選項為應(yīng)用提供Key-Value鍵值型的數(shù)據(jù)處理能力,支持應(yīng)用持久化輕量級數(shù)據(jù),常用于保存應(yīng)用配置信息、用戶偏好設(shè)置等。本篇Codelab將基于用戶首選項實現(xiàn)一個簡單的數(shù)據(jù)管理應(yīng)用,包含新增、查詢和刪除的功能。效果如圖所示:
相關(guān)概念
- [dialog]:自定義彈窗容器。
- [用戶首選項]:用戶首選項為應(yīng)用提供Key-Value鍵值型的數(shù)據(jù)處理能力,支持應(yīng)用持久化輕量級數(shù)據(jù),并對其修改和查詢。
環(huán)境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
- OpenHarmony SDK版本:API version 9及以上版本。
- 鴻蒙開發(fā)文檔參考:[
gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
硬件要求
- 開發(fā)板類型:[潤和RK3568開發(fā)板]。
- OpenHarmony系統(tǒng):3.2 Release及以上版本。
環(huán)境搭建
完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:
- [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
- 搭建燒錄環(huán)境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開發(fā)板的燒錄]
- 搭建開發(fā)環(huán)境。
- 開始前請參考[工具準備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
- 開發(fā)環(huán)境配置完成后,請參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”)。
- 工程創(chuàng)建完成后,選擇使用[真機進行調(diào)測]。
代碼結(jié)構(gòu)解讀
本篇Codelab只對核心代碼進行講解,對于完整代碼,我們會在gitee中提供。
├──entry/src/main/js // 代碼區(qū)
│ └──MainAbility
│ ├──common
│ │ ├──constants
│ │ │ └──commonConstants.js // 公共常量
│ │ ├──database
│ │ │ └──preference.js // 首選項數(shù)據(jù)處理
│ │ ├──images // 圖片圖標
│ │ │ ├──ic_delete.png
│ │ │ └──ic_no_data.png
│ │ └──utils
│ │ └──logger.js // 日志工具
│ ├──i18n // 國際化
│ │ ├──en-US.json
│ │ └──zh-CN.json
│ └──pages
│ └──index
│ ├──index.css // 首頁樣式文件
│ ├──index.hml // 首頁布局文件
│ └──index.js // 首頁腳本文件
└──entry/src/main/resources // 應(yīng)用資源目錄
構(gòu)建界面
應(yīng)用主界面由上至下分為四部分:頂部標題欄、搜索欄、數(shù)據(jù)展示區(qū)域、底部按鈕區(qū)域。
每個區(qū)域都位于div容器組件中,通過對容器位置的控制,做好頁面整體布局。
- 標題欄區(qū)域內(nèi)僅包含text組件,用于設(shè)置標題顯示內(nèi)容。
- 搜索欄區(qū)域內(nèi)僅包含search組件,用于設(shè)置搜索框的顯示。
- 數(shù)據(jù)展示區(qū)域會根據(jù)不同場景呈現(xiàn)不同內(nèi)容:無數(shù)據(jù)時,使用image組件展示“暫無數(shù)據(jù)”圖片;存在數(shù)據(jù)時,則會使用list組件展示數(shù)據(jù)列表。
- 按鈕區(qū)域使用button組件,設(shè)置“清空”和“添加”按鈕。
< !-- index.hml -- >
< div class="container" >
< !-- 標題欄 -- >
< div class="title-container" >
< text class="title" >DataBase< /text >
< /div >
< !-- 搜索欄 -- >
< div class="search-container" >
< search class="search-bar" hint="{{ $t('strings.search_key') }}" searchbutton="{{ $t('strings.search') }}"
@submit="searchByKey" >< /search >
< /div >
< !-- 數(shù)據(jù)區(qū)域(無數(shù)據(jù)) -- >
< div class="no-data-container" if="{{ isNoData }}" >
< image src='/common/images/ic_no_data.png' >< /image >
< /div >
< !-- 數(shù)據(jù)區(qū)域(有數(shù)據(jù)) -- >
< list class="data-container" if="{{ ! isNoData }}" scrollbar="auto" >
< list-item for="{{ allDataArray }}" class="list-item" >
< div class="card-container" >
< div class="text-container" >
< text class="key-text" >{{ $item.key }}< /text >
< text class="value-text" >{{ $item.value }}< /text >
< /div >
< image class="delete-img" src="/common/images/ic_delete.png" @click="deleteData({{ $item.key }})" >
< /image >
< /div >
< /list-item >
< /list >
< !-- 按鈕區(qū)域 -- >
< div class="button-container" >
< button class="remove" type="capsule" value="{{ $t('strings.delete_all') }}" @click="removeAll" >< /button >
< button class="add" type="capsule" value="{{ $t('strings.add') }}" @click="addData" >< /button >
< /div >
< /div >
當進行添加、刪除、清空等操作,會彈出對應(yīng)的對話框。對話框使用dialog自定義彈框容器組件,根據(jù)對話框需要展示的內(nèi)容選擇不同的元素。
< !-- index.hml -- >
< div class="container" >
< !-- 添加對話框 -- >
< dialog id="addDialog" class="add-dialog" >
< div class="add-dialog-container" >
< div class="add-input-container" >
< text class="add-dialog-title" >{{ $t('strings.add') }}< /text >
< input id="dataKey" class="add-dialog-input" placeholder="{{ $t('strings.key_input') }}"
@change="keyChange" >< /input >
< input id="dataValue" class="add-dialog-input" placeholder="{{ $t('strings.value_input') }}"
@change="dataChange" >< /input >
< /div >
< div class="add-button-container" >
< button type="capsule" value="{{ $t('strings.cancel') }}" onclick="addCancel" class="normal-button" >
< /button >
< button type="capsule" value="{{ $t('strings.confirm') }}" onclick="addConfirm" class="normal-button" >
< /button >
< /div >
< /div >
< /dialog >
< !-- 刪除對話框 -- >
< dialog id="deleteDialog" class="delete-dialog" >
< div class="delete-dialog-container" >
< text >{{ $t('strings.delete_hint') }}< /text >
< div class="delete-button-container" >
< button type="capsule" value="{{ $t('strings.cancel') }}" onclick="deleteCancel" class="normal-button" >
< /button >
< button type="capsule" value="{{ $t('strings.delete') }}" onclick="deleteConfirm" class="delete-button" >
< /button >
< /div >
< /div >
< /dialog >
< !-- 清空對話框 -- >
< dialog id="clearDialog" class="delete-dialog" >
< div class="delete-dialog-container" >
< text >{{ $t('strings.delete_all_hint') }}< /text >
< div class="delete-button-container" >
< button type="capsule" value="{{ $t('strings.cancel') }}" onclick="clearCancel" class="normal-button" >
< /button >
< button type="capsule" value="{{ $t('strings.delete_all') }}" onclick="clearConfirm"
class="delete-button" >< /button >
< /div >
< /div >
< /dialog >
< /div >
使用用戶首選項
使用用戶首選項,需要先導入對應(yīng)模塊,并獲取Preferences實例。
// preference.js
import dataPreferences from '@ohos.data.preferences';
let preference = null;
class Preference {
...
async initPreferences() {
try {
let context = featureAbility.getContext();
preference = await dataPreferences.getPreferences(context, CommonConstants.PREFERENCES_NAME);
} catch (err) {
logger.error(`Failed to get preferences. code: ${err.code},message: ${err.message}`);
}
}
...
}
使用put()方法寫入需要添加的數(shù)據(jù)。使用flush()方法,將用戶首選項實例緩存數(shù)據(jù)持久化到對應(yīng)文件中。
// preference.js
import dataPreferences from '@ohos.data.preferences';
let preference = null;
class Preference {
...
async addData(key, value) {
...
try {
await preference.put(key, value);
await preference.flush();
} catch (err) {
logger.error(`Fail to add data. code: ${err.code},message: ${err.message}`);
}
}
...
}
使用getAll()方法查詢所有key值,再根據(jù)所有key值查詢對應(yīng)value值。
// preference.js
import dataPreferences from '@ohos.data.preferences';
let preference = null;
class Preference {
...
async getAllData() {
let allData = [];
...
try {
let value = await preference.getAll();
let allKeys = Object.keys(value);
let keyNum = allKeys.length;
for (let i = 0; i < keyNum; i++) {
let dataObj = await this.getDataByKey(allKeys[i]);
allData.push(dataObj);
}
} catch (err) {
logger.error(`Failed to query all data. code: ${err.code},message: ${err.message}`)
}
return allData;
}
...
}
使用delete()方法刪除指定鍵值對,使用clear()方法清除此Preferences實例中的所有數(shù)據(jù)。
// preference.js
import dataPreferences from '@ohos.data.preferences';
let preference = null;
class Preference {
...
async deleteData(key) {
...
try {
await preference.delete(key);
await preference.flush();
} catch (err) {
logger.error(`Failed to delete. code: ${err.code},message: ${err.message}`);
}
}
async clearData() {
...
try {
await preference.clear();
await preference.flush();
} catch (err) {
logger.error(`Failed to clear. code: ${err.code},message: ${err.message}`);
}
}
...
}
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
60文章
2621瀏覽量
44072 -
HarmonyOS
+關(guān)注
關(guān)注
80文章
2126瀏覽量
33115 -
OpenHarmony
+關(guān)注
關(guān)注
29文章
3854瀏覽量
18639
發(fā)布評論請先 登錄
鴻蒙OS開發(fā)實例:【工具類封裝-首選項本地存儲】

如何設(shè)置Xilinx ISE首選項11.x 12.x的默認值
查看首選項未保存, 如何保存設(shè)置?
HarmonyOS IoT 硬件開發(fā)案例分享
【潤和直播課預告@華為開發(fā)者學院】HarmonyOS設(shè)備開發(fā)基礎(chǔ)課程|HiSpark WiFi-IoT 智能小車套件開發(fā)案例
ESP8266/ARDUINO構(gòu)建H找不到首選項怎么解決?
HarmonyOS數(shù)據(jù)管理與應(yīng)用數(shù)據(jù)持久化(一)
華為開發(fā)者分論壇HarmonyOS學生公開課-OpenHarmony Codelabs開發(fā)案例

評論