Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
6cd2e2f8
D
Docs
项目概览
OpenHarmony
/
Docs
接近 2 年 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
6cd2e2f8
编写于
7月 05, 2023
作者:
O
openharmony_ci
提交者:
Gitee
7月 05, 2023
浏览文件
操作
浏览文件
下载
差异文件
!20240 新增案例【不需要翻译】
Merge pull request !20240 from duangavin123/master
上级
a78c4545
432b8d3e
变更
10
展开全部
隐藏空白更改
内联
并排
Showing
10 changed file
with
1755 addition
and
0 deletion
+1755
-0
zh-cn/third-party-cases/Readme-CN.md
zh-cn/third-party-cases/Readme-CN.md
+7
-0
zh-cn/third-party-cases/delete-checkboxgroup-items.md
zh-cn/third-party-cases/delete-checkboxgroup-items.md
+358
-0
zh-cn/third-party-cases/figures/Pixel-Convertion.gif
zh-cn/third-party-cases/figures/Pixel-Convertion.gif
+0
-0
zh-cn/third-party-cases/figures/checkbox-after-improve.PNG
zh-cn/third-party-cases/figures/checkbox-after-improve.PNG
+0
-0
zh-cn/third-party-cases/figures/checkbox-before-improve.PNG
zh-cn/third-party-cases/figures/checkbox-before-improve.PNG
+0
-0
zh-cn/third-party-cases/figures/delete-checkboxitem.gif
zh-cn/third-party-cases/figures/delete-checkboxitem.gif
+0
-0
zh-cn/third-party-cases/figures/preference-storage.gif
zh-cn/third-party-cases/figures/preference-storage.gif
+0
-0
zh-cn/third-party-cases/image-format-transfer.md
zh-cn/third-party-cases/image-format-transfer.md
+225
-0
zh-cn/third-party-cases/pixel-format-transfer.md
zh-cn/third-party-cases/pixel-format-transfer.md
+814
-0
zh-cn/third-party-cases/preferences-data-process.md
zh-cn/third-party-cases/preferences-data-process.md
+351
-0
未找到文件。
zh-cn/third-party-cases/Readme-CN.md
浏览文件 @
6cd2e2f8
...
@@ -26,6 +26,9 @@
...
@@ -26,6 +26,9 @@
-
[
常见弹窗的使用
](
diverse-dialogues.md
)
-
[
常见弹窗的使用
](
diverse-dialogues.md
)
-
[
折叠展开动效
](
collapse-and-expand.md
)
-
[
折叠展开动效
](
collapse-and-expand.md
)
-
[
列表上拉加载更多内容
](
list-pullup-loading-data.md
)
-
[
列表上拉加载更多内容
](
list-pullup-loading-data.md
)
-
[
如何删除多选框选项
](
delete-checkboxgroup-items.md
)
-
[
像素单位转换
](
pixel-format-transfer.md
)
### 装饰器
### 装饰器
-
[
控制页面刷新范围
](
overall-and-part-refresh.md
)
-
[
控制页面刷新范围
](
overall-and-part-refresh.md
)
-
[
如何监听多层状态变化
](
observed-and-objectlink.md
)
-
[
如何监听多层状态变化
](
observed-and-objectlink.md
)
...
@@ -38,8 +41,12 @@
...
@@ -38,8 +41,12 @@
-
[
如何创建悬浮窗
](
float-window.md
)
-
[
如何创建悬浮窗
](
float-window.md
)
-
[
保持屏幕常亮
](
keep-screen-on.md
)
-
[
保持屏幕常亮
](
keep-screen-on.md
)
### 数据管理
-
[
用户首选项的基本使用
](
preferences-data-process.md
)
### 媒体
### 媒体
-
[
常见图片编辑
](
image-edit.md
)
-
[
常见图片编辑
](
image-edit.md
)
-
[
图片格式转换
](
image-format-transfer.md
)
### 一次开发,多端部署
### 一次开发,多端部署
-
[
Navigation如何实现多场景UI适配
](
multi-device-app-dev.md
)
-
[
Navigation如何实现多场景UI适配
](
multi-device-app-dev.md
)
...
...
zh-cn/third-party-cases/delete-checkboxgroup-items.md
0 → 100644
浏览文件 @
6cd2e2f8
# 如何删除多选框选项
## 场景说明
通常情况下,我们使用多选框都会伴随对选项的操作,比较常见的操作是选中后删除,比如删除购物车的商品、删除账单、删除图片等等。但是,当前OpenHarmony针对多选框组件并没有提供直接的删除其选项的方法,需要开发者自己来实现。本例提供了一种实现方案,供开发者参考。
## 效果呈现
本例最终效果如下:

## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
-
IDE: DevEco Studio 4.0 Beta1
-
SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本例中涉及的关键特性及实现方案如下:
-
多选框:使用CheckboxGroup组件构建多选框标题,使用Checkbox组件构建多选框选项。
-
删除多选框选项:通过CheckboxGroup的onChange回调获取到各个选项的选中状态,在删除操作中,将选中的选项从选项列表中删除。
-
删除时弹出确认框:使用promptAction模块调用showDialog方法弹出对话框,通过回调获取到用户点击的是取消按钮还是确定按钮,如果是确定按钮则执行删除操作。
## 开发步骤
1.
搭建UI布局。
整体纵向布局,那就采用Column组件;全选框用CheckboxGroup组件,然后每个选项都包括一个选择框(Checkbox组件)和一个文本(Text组件),且为横向布局,那我们可以把它们放在Flex组件中;最后是一个Button组件。这样整体布局就有了,具体代码如下:
```
ts
@
Component
struct
CheckboxDemo
{
build
(){
Column
(){
Flex
({}){
CheckboxGroup
({})
Text
(
'
水果清单
'
)
}
Flex
({}){
Checkbox
({})
Text
(
'
苹果
'
)
}
Flex
({}){
Checkbox
({})
Text
(
'
菠萝
'
)
}
Flex
({}){
Checkbox
({})
Text
(
'
柚子
'
)
}
Button
(
'
删除
'
)
}
}
}
```
框架搭好了,看下效果:

可以看到主选框和选项对齐了,接下来我们来调整下样式。
先给CheckboxGroup取个名字:fruit_list,然后为各个Checkbox添加相同的group名称,这样就可以将Checkbox挂靠到CheckboxGroup下,剩下的就是给各个组件添加margin、fontSize等通用属性了,不清楚各个组件有哪些属性的请自行查阅组件参考,具体代码如下:
```ts
@Component
struct CheckboxDemo{
build(){
Column(){
Flex({justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}){
// 将CheckboxGroup命名为'fruit_list'
CheckboxGroup({group: 'fruit_list'})
.selectedColor('#007DFF')
Text('水果清单')
.margin({right:20})
.fontSize(14)
.lineHeight(20)
.fontColor('#182431')
.fontWeight(FontWeight.Bold)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}){
// 通过group参数将Checkbox挂到CheckboxGroup下
Checkbox({name:'苹果',group:'fruit_list'})
.selectedColor('#007DFF')
Text('苹果')
.margin({right:20})
.fontSize(14)
.lineHeight(20)
.fontColor('#182431')
.fontWeight(500)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}){
Checkbox({name:'菠萝',group:'fruit_list'})
.selectedColor('#007DFF')
Text('菠萝')
.margin({right:20})
.fontSize(14)
.lineHeight(20)
.fontColor('#182431')
.fontWeight(500)
}
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}){
Checkbox({name:'柚子',group:'fruit_list'})
.selectedColor('#007DFF')
Text('柚子')
.margin({right:20})
.fontSize(14)
.lineHeight(20)
.fontColor('#182431')
.fontWeight(500)
}
Button('删除')
.margin({top:20,left:35})
.fontSize(15)
.padding({top:5,bottom:5,left:15,right:15})
}
}
}
```
我们再来看下效果,发现多选框的布局已经正常了:

2.
简化代码。
当前代码重复性很高,包含Checkbox的三个Flex的结构完全一样,我们可以简化一下。把重复的结构通过@Builder抽取出来作为一个自定义组件,用到的地方进行引用即可;每个Flex呈现的内容不同,那就将不同的内容作为参数传入。具体代码如下:
```
ts
@
Component
struct
CheckboxDemo
{
// flexNameList存储checkbox选项的文本内容;使用@State修饰后,flexNameList发生变化,UI会同步刷新
@
State
flexNameList
:
string
[]
=
[
'
苹果
'
,
'
菠萝
'
,
'
柚子
'
]
@
Builder
// 将重复内容封装成flexItem,通过参数checkboxName为Text组件传入显示文本,通过groupName绑定CheckboxGroup
flexItem
(
checkboxName
:
string
,
groupName
:
string
){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
})
{
Checkbox
({
name
:
checkboxName
,
group
:
groupName
})
.
selectedColor
(
'
#007DFF
'
)
Text
(
checkboxName
)
.
margin
({
right
:
20
})
.
fontSize
(
14
)
.
lineHeight
(
20
)
.
fontColor
(
'
#182431
'
)
.
fontWeight
(
500
)
}.
margin
({
left
:
36
})
}
build
(){
Column
(){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
}){
CheckboxGroup
({
group
:
'
fruit_list
'
})
.
selectedColor
(
'
#007DFF
'
)
Text
(
'
水果清单
'
)
.
margin
({
right
:
20
})
.
fontSize
(
14
)
.
lineHeight
(
20
)
.
fontColor
(
'
#182431
'
)
.
fontWeight
(
FontWeight
.
Bold
)
}
// 通过ForEach遍历flexNameList循环渲染生成UI
ForEach
(
this
.
flexNameList
,(
item
:
any
)
=>
{
// 引用封装的flexItem模板
this
.
flexItem
(
item
,
'
fruit_list
'
)
})
Button
(
'
删除
'
)
.
margin
({
top
:
20
,
left
:
35
})
.
fontSize
(
15
)
.
padding
({
top
:
5
,
bottom
:
5
,
left
:
15
,
right
:
15
})
}.
alignItems
(
HorizontalAlign
.
Center
)
}
}
```
3.
添加删除逻辑。
本例中是通过以下方式实现删除操作的:将选中的水果项从flexNameList中删除(为方便展示,本文直接将数据存储在数组中,实际开发需要对接数据库),由于flexNameList被@State修饰,所以其发生变化时会重新执行Build(),从而完成UI刷新,展示删除后的选项。
要实现上述逻辑,首先需要获取到被选中的水果项。这里可以通过CheckboxGroup的onChange回调获取,当选项的状态发生变化时,会触发回调并返回各选项的选中状态。
具体代码如下:
```
ts
@
Component
struct
CheckboxDemo
{
...
// itemStatus用来存储各选项的选中状态
private
itemStatus
:
CheckboxGroupResult
...
build
(){
Column
(){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
}){
CheckboxGroup
({
group
:
'
fruit_list
'
})
.
selectedColor
(
'
#007DFF
'
)
// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表
.
onChange
((
itemName
:
CheckboxGroupResult
)
=>
{
this
.
itemStatus
=
itemName
})
...
}.
alignItems
(
HorizontalAlign
.
Center
)
}
}
```
将各选项的选中状态存储到itemStatus后,我们就可以通过Button触发删除操作了。当点击删除按钮时,触发删除操作,所以给Button添加onClick事件,并添加删除逻辑。代码如下:
```
ts
@
Component
struct
CheckboxDemo
{
......
// itemStatus用来存储各选项的选中状态
private
itemStatus
:
CheckboxGroupResult
......
build
(){
Column
(){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
}){
CheckboxGroup
({
group
:
'
fruit_list
'
})
.
selectedColor
(
'
#007DFF
'
)
// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表
.
onChange
((
itemName
:
CheckboxGroupResult
)
=>
{
this
.
itemStatus
=
itemName
})
......
Button
(
'
删除
'
)
.
margin
({
top
:
20
,
left
:
35
})
.
fontSize
(
15
)
.
padding
({
top
:
5
,
bottom
:
5
,
left
:
15
,
right
:
15
})
// 点击触发删除操作
.
onClick
(()
=>
{
// 被选中的项存储在this.itemStatus.name列表中
for
(
let
i
of
this
.
itemStatus
.
name
){
// 从flexNameList中删除被选中的项,刷新UI
this
.
flexNameList
.
splice
(
this
.
flexNameList
.
indexOf
(
i
),
1
)
}
})
}.
alignItems
(
HorizontalAlign
.
Center
)
}
}
```
4.
添加删除确认框。
使用promptAction模块调用showDialog方法弹出对话框,然后将删除操作绑定到对话框的确定按钮,具体代码如下:
```
ts
// 导入promptAction模块
import
promptAction
from
'
@ohos.promptAction
'
;
@
Component
struct
CheckboxDemo
{
......
// itemStatus用来存储各选项的选中状态
private
itemStatus
:
CheckboxGroupResult
......
build
(){
Column
(){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
}){
CheckboxGroup
({
group
:
'
fruit_list
'
})
.
selectedColor
(
'
#007DFF
'
)
// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表
.
onChange
((
itemName
:
CheckboxGroupResult
)
=>
{
this
.
itemStatus
=
itemName
})
......
Button
(
'
删除
'
)
.
margin
({
top
:
20
,
left
:
35
})
.
fontSize
(
15
)
.
padding
({
top
:
5
,
bottom
:
5
,
left
:
15
,
right
:
15
})
// 点击触发删除操作
.
onClick
(()
=>
{
// 调用对话框
promptAction
.
showDialog
({
title
:
''
,
message
:
'
确定删除吗?
'
,
buttons
:[
{
text
:
'
取消
'
,
color
:
'
#000000
'
},
{
text
:
'
确定
'
,
color
:
'
#000000
'
}
]
})
// 用户选择通过data回传,当data.index为1时,用户选择确定,当data.index为0时,用户选择取消
.
then
(
data
=>
{
// 当用户选择确定时,进行删除操作
if
(
data
.
index
===
1
){
// 被选中的项存储在this.itemStatus.name列表中
for
(
let
i
of
this
.
itemStatus
.
name
){
// 从flexNameList中删除被选中的项,刷新UI
this
.
flexNameList
.
splice
(
this
.
flexNameList
.
indexOf
(
i
),
1
)
}
}
})
})
}.
alignItems
(
HorizontalAlign
.
Center
)
}
}
```
## 完整代码
本例完整代码如下:
```
ts
import
promptAction
from
'
@ohos.promptAction
'
;
@
Entry
@
Component
struct
CheckboxDemo
{
@
State
flexNameList
:
string
[]
=
[
'
苹果
'
,
'
菠萝
'
,
'
柚子
'
]
private
itemStatus
:
CheckboxGroupResult
@
Builder
flexItem
(
checkboxName
:
string
,
groupName
:
string
){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
})
{
Checkbox
({
name
:
checkboxName
,
group
:
groupName
})
.
selectedColor
(
'
#007DFF
'
)
Text
(
checkboxName
)
.
margin
({
right
:
20
})
.
fontSize
(
14
)
.
lineHeight
(
20
)
.
fontColor
(
'
#182431
'
)
.
fontWeight
(
500
)
}.
margin
({
left
:
36
})
}
build
()
{
Column
()
{
if
(
this
.
flexNameList
.
length
!=
0
){
Flex
({
justifyContent
:
FlexAlign
.
Center
,
alignItems
:
ItemAlign
.
Center
})
{
CheckboxGroup
({
group
:
'
fruit_list
'
})
.
selectedColor
(
'
#007DFF
'
)
.
onChange
((
itemName
:
CheckboxGroupResult
)
=>
{
this
.
itemStatus
=
itemName
})
Text
(
'
水果清单
'
)
.
margin
({
right
:
20
})
.
fontSize
(
14
)
.
lineHeight
(
20
)
.
fontColor
(
'
#182431
'
)
.
fontWeight
(
FontWeight
.
Bold
)
}.
margin
({
top
:
150
})
ForEach
(
this
.
flexNameList
,(
item
:
any
)
=>
{
this
.
flexItem
(
item
,
'
fruit_list
'
)
})
Button
(
"
删除
"
)
.
margin
({
top
:
20
,
left
:
35
})
.
fontSize
(
15
)
.
padding
({
top
:
5
,
bottom
:
5
,
left
:
15
,
right
:
15
})
.
onClick
(()
=>
{
promptAction
.
showDialog
({
title
:
''
,
message
:
'
确定删除吗?
'
,
buttons
:[
{
text
:
'
取消
'
,
color
:
'
#000000
'
},
{
text
:
'
确定
'
,
color
:
'
#000000
'
}
]
})
.
then
(
data
=>
{
if
(
data
.
index
===
1
){
for
(
let
i
of
this
.
itemStatus
.
name
){
this
.
flexNameList
.
splice
(
this
.
flexNameList
.
indexOf
(
i
),
1
)
}
}
})
})
}
else
{
}
}.
alignItems
(
HorizontalAlign
.
Center
)
}
}
```
## 参考
-
[
ChecckboxGroup
](
../application-dev/reference/arkui-ts/ts-basic-components-checkboxgroup.md
)
-
[
Checkbox
](
../application-dev/reference/arkui-ts/ts-basic-components-checkbox.md
)
-
[
Flex
](
../application-dev/reference/arkui-ts/ts-container-flex.md
)
-
[
Button
](
../application-dev/reference/arkui-ts/ts-basic-components-button.md
)
-
[
ohos.promptAction (弹窗)
](
../application-dev/reference/apis/js-apis-promptAction.md
)
-
[
ForEach循环渲染
](
../application-dev/quick-start/arkts-rendering-control-foreach.md
)
-
[
@State状态管理
](
../application-dev/quick-start/arkts-state.md
)
-
[
@Builder动态构建UI元素
](
../application-dev/quick-start/arkts-builder.md
)
\ No newline at end of file
zh-cn/third-party-cases/figures/Pixel-Convertion.gif
0 → 100644
浏览文件 @
6cd2e2f8
77.1 KB
zh-cn/third-party-cases/figures/checkbox-after-improve.PNG
0 → 100644
浏览文件 @
6cd2e2f8
13.9 KB
zh-cn/third-party-cases/figures/checkbox-before-improve.PNG
0 → 100644
浏览文件 @
6cd2e2f8
15.0 KB
zh-cn/third-party-cases/figures/delete-checkboxitem.gif
0 → 100644
浏览文件 @
6cd2e2f8
140.4 KB
zh-cn/third-party-cases/figures/preference-storage.gif
0 → 100644
浏览文件 @
6cd2e2f8
353.7 KB
zh-cn/third-party-cases/image-format-transfer.md
0 → 100644
浏览文件 @
6cd2e2f8
# 如何转换图片格式
## 场景说明
当我们获取到图片或者视频的缩略图后,返回的是pixelMap,此时有开发者会有疑问如何将pixelMap转换成jpeg等其他格式的图片,其实使用image类中的packing方法就可以将pixelMap重新打包成新的格式(当前只支持jpeg,webp格式),再使用文件管理就可以将图片存入到应用的沙箱路径。本例即为大家介绍如何完成图片格式转换。
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
-
IDE: DevEco Studio 4.0 Beta1
-
SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 效果呈现
本例最终实现效果为:将工程资源文件中png格式的图片转换为jpg格式,并保存在设备中。由于本例不涉及UI讲解,所以不在此提供UI效果。
## 实现思路
本例中完成图片格式转换包含三个关键步骤,相关步骤及实现方案如下:
-
获取到要转换图片的PixelMap数据:使用image的createPixelMap方法获取到图片的PixelMap数据。
-
将图片的PixelMap重新打包转换为其他格式:使用packing方法进行打包,打包时可以设置格式、压缩质量等。
-
将重新打包好的图片保存到应用目录:使用图库选择器photoViewPicker的相关功能以及file读写操作完成图片的保存。
## 开发步骤
由于本例重点讲解图片格式的转换,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。
1.
获取要转换图片的PixelMap数据。
先通过上下文context获取到资源管理器resourceManager,然后通过资源管理器获取到图片数据,然后获取图片的ArrayBuffer,最后通过ArrayBuffer创建imageSource,获取到pixelMap,完成图片解码。
具体代码如下:
```ts
import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
...
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext
...
async getPixelMap(){
// 获取resourceManager资源管理
const resourceMgr = this.context.resourceManager
// 获取rawfile文件夹下imagetransfer.PNG的ArrayBuffer
const fileData = await resourceMgr.getMediaContent($r('app.media.imagetransfer'))
const buffer = fileData.buffer
// 创建imageSource
const imageSource = image.createImageSource(buffer)
// 获取PixelMap
const pixelMap = await imageSource.createPixelMap()
return pixelMap
}
...
}
```
2.
将图片的PixelMap重新打包转换为其他格式。
先通过createImagePacker构建ImagePacker实例,再通过该实例调用packing方法进行打包,打包时传入获取到的PixelMap数据及重新打包的图片格式等相关配置信息。
具体代码如下:
```ts
...
@State src:PixelMap = undefined
...
// 页面加载前将获取到的图片PixelMap数据赋值给状态变量src
async aboutToAppear() {
this.src = await this.getPixelMap()
}
...
// 创建ImagePacker实例
let imagePackerApi = image.createImagePacker();
let options = {
// 设置重新打包的图片格式
format: 'image/jpeg',
quality: 98
};
// 打包时传入图片的PixelMap:src和图片打包选项:option,异步获取打包后的数据data
imagePackerApi.packing(this.src, options).then((data) => {
console.log('Succeeded in packing the image.');
}).catch(error => {
console.log('Failed to pack the image..');
....
})
```
3.
将重新打包好的图片保存到应用目录。
使用图库选择器photoViewPicker保存文件,保存时可以在保存界面选择保存路径并设定文件名。此时保存的是空文件,然后再使用file将重新打包的图片数据写入保存的文件中,保存完成后我们便可以在保存路径下找到转换格式后的图片文件了。
具体代码如下:
```ts
...
// 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data
imagePackerApi.packing(this.src, options).then((data) => {
// 创建文件管理器保存选项实例
let photoSaveOptions = new picker.PhotoSaveOptions();
// 保存文件名(可选)
photoSaveOptions.newFileNames = ["imageTransfer.jpg"];
let photoViewPicker = new picker.PhotoViewPicker();
// 保存时传入保存的文件名:photoSaveOptions
photoViewPicker.save(photoSaveOptions)
.then((photoSaveResult) => {
setTimeout(() => {
// 获取到保存文件的URI,后续进行文件读取等操作
this.uri = photoSaveResult[0];
fs.open(this.uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).then((file) => {
// 将图片打包数据data写入保存的文件
fs.write(file.fd, data).then((number) => {
console.info("foo imagetest: write data to file succeed and size is:" + number);
}).catch((err) => {
console.info("foo imagetest: write data to file failed with error:" + err);
});
// 完成文件写入后,关闭文件
fs.close(file, (err) => {
if (err) {
console.info("close file failed with error message: " + err.message + ", error code: " + err.code);
} else {
console.info("close file success");
}
});
}).catch((err) => {
console.info("foo open file failed with error message: " + err.message + ", error code: " + err.code);
});
}, 200)
})
.catch((err) => {
console.error('PhotoViewPicker.save failed with err: ' + err);
})
})
...
```
## 完整代码
本例完整代码如下:
```
ts
import
image
from
'
@ohos.multimedia.image
'
;
import
fs
from
'
@ohos.file.fs
'
;
import
common
from
'
@ohos.app.ability.common
'
;
import
picker
from
'
@ohos.file.picker
'
;
@
Entry
@
Component
struct
Index
{
@
State
src
:
PixelMap
=
undefined
context
:
common
.
UIAbilityContext
=
getContext
(
this
)
as
common
.
UIAbilityContext
private
uri
=
null
// 页面加载前将获取到的图片PixelMap数据赋值给状态变量src
async
aboutToAppear
()
{
this
.
src
=
await
this
.
getPixelMap
()
}
async
getPixelMap
(){
// 获取resourceManager资源管理
const
resourceMgr
=
this
.
context
.
resourceManager
// 获取rawfile文件夹下httpimage.PNG的ArrayBuffer
const
fileData
=
await
resourceMgr
.
getMediaContent
(
$r
(
'
app.media.contact6
'
))
const
buffer
=
fileData
.
buffer
// 创建imageSource
const
imageSource
=
image
.
createImageSource
(
buffer
)
// 创建PixelMap
const
pixelMap
=
await
imageSource
.
createPixelMap
()
return
pixelMap
console
.
log
(
'
pixelMap
'
+
JSON
.
stringify
(
this
.
src
.
getPixelBytesNumber
()))
}
build
()
{
Row
()
{
Column
()
{
Button
(
'
转换图片格式:png->jpeg
'
)
.
onClick
(()
=>
{
// 创建ImagePacker实例
let
imagePackerApi
=
image
.
createImagePacker
();
// 设置重新打包的图片格式,及图片压缩质量
let
options
=
{
format
:
'
image/jpeg
'
,
quality
:
98
};
// 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data
imagePackerApi
.
packing
(
this
.
src
,
options
).
then
((
data
)
=>
{
// 创建文件管理器保存选项实例
let
photoSaveOptions
=
new
picker
.
PhotoSaveOptions
();
// 保存文件名(可选)
photoSaveOptions
.
newFileNames
=
[
"
imageTransfer.jpg
"
];
let
photoViewPicker
=
new
picker
.
PhotoViewPicker
();
// 保存时传入保存的文件名:photoSaveOptions
photoViewPicker
.
save
(
photoSaveOptions
)
.
then
((
photoSaveResult
)
=>
{
console
.
log
(
'
foo start
'
)
setTimeout
(()
=>
{
// 获取到图片的URI后进行文件读取等操作
this
.
uri
=
photoSaveResult
[
0
];
fs
.
open
(
this
.
uri
,
fs
.
OpenMode
.
READ_WRITE
|
fs
.
OpenMode
.
CREATE
).
then
((
file
)
=>
{
// 将图片打包数据data写入保存的文件
fs
.
write
(
file
.
fd
,
data
).
then
((
number
)
=>
{
console
.
info
(
"
foo imagetest: write data to file succeed and size is:
"
+
number
);
}).
catch
((
err
)
=>
{
console
.
info
(
"
foo imagetest: write data to file failed with error:
"
+
err
);
});
// 完成文件写入后,关闭文件
fs
.
close
(
file
,
(
err
)
=>
{
if
(
err
)
{
console
.
info
(
"
close file failed with error message:
"
+
err
.
message
+
"
, error code:
"
+
err
.
code
);
}
else
{
console
.
info
(
"
close file success
"
);
}
});
}).
catch
((
err
)
=>
{
console
.
info
(
"
foo open file failed with error message:
"
+
err
.
message
+
"
, error code:
"
+
err
.
code
);
});
},
200
)
})
.
catch
((
err
)
=>
{
console
.
error
(
'
PhotoViewPicker.save failed with err:
'
+
err
);
})
})
})
}
.
width
(
'
100%
'
)
}
.
height
(
'
100%
'
)
}
}
```
## 参考
-
[
@ohos.multimedia.image (图片处理)
](
../application-dev/reference/apis/js-apis-image.md
)
-
[
@ohos.file.fs (文件管理)
](
../application-dev/reference/apis/js-apis-file-fs.md
)
-
[
@ohos.file.picker (选择器)
](
../application-dev/reference/apis/js-apis-file-picker.md
)
\ No newline at end of file
zh-cn/third-party-cases/pixel-format-transfer.md
0 → 100644
浏览文件 @
6cd2e2f8
此差异已折叠。
点击以展开。
zh-cn/third-party-cases/preferences-data-process.md
0 → 100644
浏览文件 @
6cd2e2f8
# 用户首选项的基本使用
## 场景说明
用户首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。当用户希望有一个全局唯一存储的地方,可以采用用户首选项来进行存储。用户首选项会将该数据缓存在内存中,当用户读取的时候,能够快速从内存中获取数据。用户首选项会随着存放的数据量越多而导致应用占用的内存越大,因此,用户首选项不适合存放过多的数据,适用的场景一般为应用保存用户的个性化设置(屏幕亮度,是否开启夜间模式)等。
本例以一个小示例为大家介绍如何使用用户首选项对数据进行存储、获取、删除。
## 效果呈现
本例最终效果如下:

## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
-
IDE: DevEco Studio 4.0 Beta1
-
SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本例以设置屏幕亮度为例演示如何使用用户首选项管理数据,主要特性及实现方式如下:
-
当用户在文本框输入数据后,点击保存数据,用户首选项将数据缓存在内存中:通过dataPreferences类的getPreferences方法获取用户首选项实例,然后通过该实例调用put方法将数据写入内存。
-
当用户点击读取数据时,用户首选项将数据从内存中读取出来并显示在输入框中:通过用户首选项实例调用get方法获取到保存的数据,显示在输入框中。
-
当用户点击删除数据时,用户首选项将数据从内存中删除,用户无法继续读取数据:通过用户首选项实例调用delete方法删除保存的数据。
>  **说明:**
> 用户首选项的使用需要注意以下几点:
> - Key键为string类型,要求非空且长度不超过80个字节。
> - 如果Value值为string类型,请使用UTF-8编码格式,可以为空,不为空时长度不超过8192个字节。
> - 内存会随着存储数据量的增大而增大,所以存储的数据量应该是轻量级的,建议存储的数据不超过一万条,否则会在内存方面产生较大的开销。
## 开发步骤
由于本例重点讲解用户首选项的数据管理操作,所以开发步骤会着重讲解如何通过用户首选项完成数据的存储、读取和删除,全量代码可参考完整代码章节。
1.
首先自定义一个用户首选项类,根据业务封装相关方法方便后续调用。
其中包含数据处理的方法,用于完成数据的存储、读取和删除操作。用户首选项接口的使用方式主要在这部分呈现,需要重点关注。
具体代码如下:
```
ts
import
dataPreferences
from
'
@ohos.data.preferences
'
;
import
promptAction
from
'
@ohos.promptAction
'
;
import
ScreenBrightness
from
'
../common/bean/Brightness
'
;
let
context
=
getContext
(
this
);
let
preference
:
dataPreferences
.
Preferences
=
null
;
// 自定义用户首选项类
class
PreferenceModel
{
private
brightness
:
ScreenBrightness
// 创建用户首选项实例preference
async
getPreferencesFromStorage
()
{
try
{
preference
=
await
dataPreferences
.
getPreferences
(
context
,
'
setting.db
'
);
}
catch
(
err
)
{
Logger
.
error
(
'
[PreferenceModel]
'
,
`Failed to get preferences, Cause:
${
err
}
`
);
}
}
// 删除数据,调用dataPreferences的deletePreferences接口
async
deletePreferences
()
{
try
{
await
dataPreferences
.
deletePreferences
(
context
,
'
setting.db
'
);
}
catch
(
err
)
{
Logger
.
error
(
'
[PreferenceModel]
'
,
`Failed to delete preferences, Cause:
${
err
}
`
);
};
preference
=
null
;
this
.
showToastMessage
(
$r
(
'
app.string.delete_success_msg
'
));
}
// 保存数据
async
putPreference
(
screenBrightness
:
ScreenBrightness
)
{
if
(
preference
===
null
)
{
await
this
.
getPreferencesFromStorage
();
}
// 将用户输入的亮度数据保存到preference,调用用户首选项实例的put接口
try
{
await
preference
.
put
(
'
screenBrightness
'
,
JSON
.
stringify
(
screenBrightness
));
}
catch
(
err
)
{
Logger
.
error
(
'
[PreferenceModel]
'
,
`Failed to put value, Cause:
${
err
}
`
);
}
// 使用flush方法将preferences实例的数据存储到持久化文件,调用用户首选项实例的flush接口
await
preference
.
flush
();
}
// 获取数据,调用用户首选项实例的get接口
async
getPreference
()
{
let
screenBrightness
=
''
;
if
(
preference
===
null
)
{
await
this
.
getPreferencesFromStorage
();
}
try
{
screenBrightness
=
<
string
>
await
preference
.
get
(
'
screenBrightness
'
,
''
);
}
catch
(
err
)
{
Logger
.
error
(
'
[PreferenceModel]
'
,
`Failed to get value, Cause:
${
err
}
`
);
}
// 如果判断数据为空则提示用户先输入数据
if
(
screenBrightness
===
''
)
{
this
.
showToastMessage
(
$r
(
'
app.string.data_is_null_msg
'
));
return
;
}
this
.
showToastMessage
(
$r
(
'
app.string.read_success_msg
'
));
return
JSON
.
parse
(
screenBrightness
);
}
// 校验用户输入是否为空
checkData
(
screenBrightness
:
ScreenBrightness
)
{
if
(
screenBrightness
.
brightSwitch
===
''
||
screenBrightness
.
defaultValue
===
''
)
{
this
.
showToastMessage
(
$r
(
'
app.string.fruit_input_null_msg
'
));
return
true
;
}
return
false
;
}
// 点击保存按钮保存数据
writeData
(
screenBrightness
:
ScreenBrightness
)
{
// Check whether the data is null.
let
isDataNull
=
this
.
checkData
(
screenBrightness
);
if
(
isDataNull
)
{
return
;
}
// The data is inserted into the preferences database if it is not empty.
this
.
putPreference
(
screenBrightness
);
this
.
showToastMessage
(
$r
(
'
app.string.write_success_msg
'
));
}
// 消息弹框
showToastMessage
(
message
:
Resource
)
{
promptAction
.
showToast
({
message
:
message
,
duration
:
3000
});
};
}
```
2.
UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下:
文本和输入框子组件:
```
ts
import
ScreenBrightness
from
'
../common/bean/Brightness
'
;
@
Component
export
default
struct
TextItemComponent
{
private
textResource
:
Resource
;
private
placeholderResource
:
Resource
;
private
marginBottom
:
string
;
private
marginTop
:
string
;
private
textInputType
:
InputType
;
private
textFlag
:
number
;
@
Link
screenBrightness
:
ScreenBrightness
;
private
textInputCallBack
:
(
value
:
string
)
=>
void
;
aboutToAppear
()
{
if
(
this
.
textFlag
===
0
)
{
this
.
marginTop
=
'
8%
'
;
this
.
marginBottom
=
'
4%
'
;
this
.
textInputType
=
InputType
.
Normal
;
}
else
{
this
.
marginBottom
=
'
321vp
'
;
this
.
textInputType
=
InputType
.
Number
;
}
}
build
()
{
Column
()
{
// 文本
Text
(
this
.
textResource
)
.
fontSize
(
25
)
.
height
(
'
3.2%
'
)
.
width
(
'
100%
'
)
.
fontColor
(
"
#182431
"
)
.
letterSpacing
(
'
1.58
'
)
.
fontWeight
(
500
)
.
margin
({
bottom
:
'
2%
'
,
left
:
'
7%
'
,
top
:
this
.
marginTop
})
// 输入框
TextInput
({
placeholder
:
this
.
placeholderResource
,
text
:
this
.
textFlag
===
0
?
(
this
.
screenBrightness
.
brightSwitch
)
:
(
this
.
screenBrightness
.
defaultValue
)
})
.
placeholderFont
({
size
:
20
,
weight
:
500
})
.
placeholderColor
(
"
#BDC1C4
"
)
.
caretColor
(
Color
.
Blue
)
.
type
(
this
.
textInputType
)
.
height
(
'
7%
'
)
.
width
(
'
93%
'
)
.
margin
({
bottom
:
this
.
marginBottom
})
.
fontSize
(
20
)
.
fontColor
(
"
#182431
"
)
.
fontWeight
(
500
)
.
backgroundColor
(
"
#FFFFFF
"
)
.
onChange
((
value
:
string
)
=>
{
this
.
textInputCallBack
(
value
);
})
}
}
}
```
按钮子组件:
```
ts
import
PreferenceModel
from
'
../model/PreferenceModel
'
;
import
ButtonItemData
from
'
../common/bean/ButtonItemData
'
;
import
ScreenBrightness
from
'
../common/bean/Brightness
'
;
@
Component
export
default
struct
ButtonComponent
{
private
buttonItemValues
:
Array
<
ButtonItemData
>
=
this
.
getButtonItemValues
();
@
Link
screenBrightness
:
ScreenBrightness
;
build
()
{
Column
()
{
ForEach
(
this
.
buttonItemValues
,
(
item
)
=>
{
Button
(
item
.
text
,
{
type
:
ButtonType
.
Capsule
,
stateEffect
:
true
})
.
backgroundColor
(
"
#E8A027
"
)
.
width
(
'
87%
'
)
.
height
(
'
6%
'
)
.
fontWeight
(
500
)
.
fontSize
(
20
)
.
margin
({
bottom
:
'
24vp
'
})
.
onClick
(()
=>
{
item
.
clickMethod
();
})
},
item
=>
JSON
.
stringify
(
item
))
}
}
// 在foreach中渲染Button组件时传入不同按钮的参数
getButtonItemValues
()
{
let
values
:
Array
<
ButtonItemData
>
=
[
new
ButtonItemData
(
'
保存数据
'
,
()
=>
{
// 调用保存方法
PreferenceModel
.
writeData
(
this
.
screenBrightness
);
}
),
new
ButtonItemData
(
'
读取数据
'
,
()
=>
{
// 调用读取方法
PreferenceModel
.
getPreference
().
then
(
resultData
=>
{
this
.
screenBrightness
=
resultData
;
console
.
info
(
'
dbdata is
'
+
JSON
.
stringify
(
resultData
))
});
}
),
new
ButtonItemData
(
'
删除数据
'
,
()
=>
{
// 调用删除方法
PreferenceModel
.
deletePreferences
();
// 数据删除后将相关内容置为空
this
.
screenBrightness
.
brightSwitch
=
''
;
this
.
screenBrightness
.
defaultValue
=
''
}
)
];
return
values
;
}
}
```
3.
构建首页UI。
在页面生命周期的aboutToAppear中调用自定义首选项类的getPreference方法获取到保存的数据,这样如果用户之前有保存数据的话,进入应用中就可以显示之前保存的数据。
具体代码如下:
```
ts
import
PreferenceModel
from
'
../model/PreferenceModel
'
;
import
ButtonComponent
from
'
../view/ButtonComponent
'
;
import
TextItemComponent
from
'
../view/TextItemComponent
'
;
import
ScreenBrightness
from
'
../common/bean/Brightness
'
;
@
Entry
@
Component
struct
Setting
{
@
State
screenBrightness
:
ScreenBrightness
=
new
ScreenBrightness
(
''
,
''
);
build
()
{
Column
()
{
// 亮度调节文本及文本框
TextItemComponent
({
textResource
:
$r
(
'
app.string.brightness_text
'
),
placeholderResource
:
$r
(
'
app.string.brightness_placeholder
'
),
textFlag
:
0
,
screenBrightness
:
$screenBrightness
,
textInputCallBack
:
(
value
)
=>
{
this
.
screenBrightness
.
brightSwitch
=
value
;
}
})
// 设定值文本及文本框
TextItemComponent
({
textResource
:
$r
(
'
app.string.defaultValue_text
'
),
placeholderResource
:
$r
(
'
app.string.defaultValue_placeholder
'
),
textFlag
:
1
,
screenBrightness
:
$screenBrightness
,
textInputCallBack
:
(
value
)
=>
{
this
.
screenBrightness
.
defaultValue
=
value
;
}
})
// 按钮
ButtonComponent
({
screenBrightness
:
$screenBrightness
})
}
.
width
(
'
100%
'
)
.
height
(
'
100%
'
)
.
backgroundColor
(
"
#F1F3F5
"
)
}
async
aboutToAppear
()
{
await
PreferenceModel
.
getPreferencesFromStorage
();
// 获取到之前保存的数据,显示在输入框中
PreferenceModel
.
getPreference
().
then
(
resultData
=>
{
this
.
screenBrightness
=
resultData
;
});
}
}
```
## 完整代码
由于开发步骤中已经展示了大部分完整代码,此处补充前文中未呈现的两个数据类:
亮度数据类:
```
ts
export
default
class
ScreenBrightness
{
// 亮度调节
brightSwitch
:
string
;
// 设定值
defaultValue
:
string
;
constructor
(
brightSwitch
:
string
,
defaultValue
:
string
)
{
this
.
brightSwitch
=
brightSwitch
;
this
.
defaultValue
=
defaultValue
;
}
}
```
按钮数据类:
```
ts
export
default
class
ButtonItemData
{
// 按钮文本
text
:
string
;
// 按钮点击事件触发的方法
clickMethod
:
()
=>
void
;
constructor
(
text
:
string
,
clickMethod
:
()
=>
void
)
{
this
.
text
=
text
;
this
.
clickMethod
=
clickMethod
;
}
}
```
## 参考
-
[
@ohos.data.preferences (用户首选项)
](
../application-dev/reference/apis/js-apis-data-preferences.md
)
-
[
通过用户首选项实现数据持久化
](
../application-dev/database/data-persistence-by-preferences.md
)
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录