應用場景:
智能家居。
今天打造的這一款全新智能家庭控制系統,凸顯應用在智能控制和用戶體驗的特點,開創國內智能家居系統體驗新局面。新的系統主要應用在鴻蒙生態。
在開始之前大家可以先預覽一下我完成之后的效果。
智能家居中控
是不是很炫酷呢?
搭建OpenHarmony環境
完成本篇Codelab我們首先要完成開發環境的搭建,本示例以DaYu200開發板為例,參照以下步驟進行:
獲取OpenHarmony系統版本:標準系統解決方案(二進制)
以3.0版本為例:
搭建燒錄環境
完成DevEco Device Tool的安裝
完成Dayu200開發板的燒錄
搭建開發環境
開始前請參考工具準備 ,完成DevEco Studio的安裝和開發環境配置。
開發環境配置完成后,請參考使用工程向導 創建工程(模板選擇“Empty Ability”),選擇eTS語言開發。
工程創建完成后,選擇使用真機進行調測 。
相關概念
容器組件
Column
Row
Stack
基礎組件
Text
TextInput
Button
Image
Navigation
通用
邊框設置
尺寸設置
點擊控制
布局約束
背景設置
點擊事件
TS語法糖
好的接下來我將詳細講解如何制作
開發教學
創建好的 eTS工程目錄
新建工程的ETS目錄如下圖所示。
各個文件夾和文件的作用:
index.ets:用于描述UI布局、樣式、事件交互和頁面邏輯。
app.ets:用于全局應用邏輯和應用生命周期管理。
pages:用于存放所有組件頁面。
resources:用于存放資源配置文件。
接下來開始正文。
我們的主要操作都是在在pages目錄中,然后我將用不到10分鐘的時間,帶大家實現這個功能。
拆解
根據設計圖,我們可以分層展示,用Column包裹,大致分為這幾步
可以看下本頁的結構:
再詳細一點:
import
{
SettingDetails
}
from
'./common/SettingDetails'
;
import
router
from
'@ohos.router'
;
?
@
Entry
@
Component
struct
Index
{
@
State
title
:
string
=
'智能家居體驗'
@
State
message
:
string
=
'你現在想要打開那些設置?'
@
State
desc
:
string
=
'點擊所有適用的選項。這將幫助我們\n自定義您的主頁'
@
State
Number
:
String
[]
=
[
'0'
,
'1'
,
'2'
,
'3'
,
'4'
]
@
State
private
isSelect
:
boolean
=
true
;
?
build
() {
?
Column
() {
Text
(
this
.
title
)
.
fontSize
(
80
)
.
fontWeight
(
FontWeight
.
Bold
).
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
}).
margin
({
bottom
:
60
,
top
:
40
})
Text
(
this
.
message
)
.
fontSize
(
50
)
.
fontWeight
(
FontWeight
.
Bold
).
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
}).
margin
({
bottom
:
60
})
Text
(
this
.
desc
)
.
fontSize
(
30
)
.
textAlign
(
TextAlign
.
Center
)
.
fontWeight
(
FontWeight
.
Bold
)
.
onClick
(()
=>
{
?
})
.
margin
({
bottom
:
60
})
Row
() {
?
SettingDetails
({
image
:
"common/images/setting.png"
,
title
:
"Maintenance\nRequests"
,
isSelected
:
this
.
isSelect
!
})
?
SettingDetails
({
image
:
"common/images/grain.png"
,
title
:
"Integrations\n"
,
isSelected
:
this
.
isSelect
!
})
?
SettingDetails
({
image
:
"common/images/ic_highlight.png"
,
title
:
"Light\nControl"
,
isSelected
:
this
.
isSelect
!
})
?
}
Row
() {
SettingDetails
({
image
:
"common/images/opacity.png"
,
title
:
"Leak\nDetector"
,
isSelected
:
this
.
isSelect
!
})
SettingDetails
({
image
:
"common/images/ac_unit.png"
,
title
:
"Temperature\nControl"
,
isSelected
:
this
.
isSelect
!
})
SettingDetails
({
image
:
"common/images/key.png"
,
title
:
"Guest\nAccess"
,
isSelected
:
this
.
isSelect
!
})
?
?
}
Button
(
"NEXT"
)
.
fontSize
(
60
)
.
fontColor
(
Color
.
Black
)
.
width
(
600
)
.
height
(
100
)
.
backgroundColor
(
Color
.
Red
)
.
margin
({
top
:
100
})
.
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
})
}
.
width
(
'100%'
)
.
height
(
'100%'
).
backgroundColor
(
"#F5F5F5"
)
}
}
具體布局
具體布局設計到一些細節的地方,例如間隔,邊框,當前組件尺寸設置等一些特殊情況,基本上就是嵌套,一層一層去實現。
代碼結構
編碼
Index.ets
import
{
SettingDetails
}
from
'./common/SettingDetails'
;
import
router
from
'@ohos.router'
;
?
@
Entry
@
Component
struct
Index
{
@
State
title
:
string
=
'智能家居體驗'
@
State
message
:
string
=
'你現在想要打開那些設置?'
@
State
desc
:
string
=
'點擊所有適用的選項。這將幫助我們\n自定義您的主頁'
@
State
Number
:
String
[]
=
[
'0'
,
'1'
,
'2'
,
'3'
,
'4'
]
@
State
private
isSelect
:
boolean
=
true
;
?
build
() {
?
Column
() {
Text
(
this
.
title
)
.
fontSize
(
80
)
.
fontWeight
(
FontWeight
.
Bold
).
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
}).
margin
({
bottom
:
60
,
top
:
40
})
Text
(
this
.
message
)
.
fontSize
(
50
)
.
fontWeight
(
FontWeight
.
Bold
).
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
}).
margin
({
bottom
:
60
})
Text
(
this
.
desc
)
.
fontSize
(
30
)
.
textAlign
(
TextAlign
.
Center
)
.
fontWeight
(
FontWeight
.
Bold
)
.
onClick
(()
=>
{
?
})
.
margin
({
bottom
:
60
})
Row
() {
?
SettingDetails
({
image
:
"common/images/setting.png"
,
title
:
"Maintenance\nRequests"
,
isSelected
:
this
.
isSelect
!
})
?
SettingDetails
({
image
:
"common/images/grain.png"
,
title
:
"Integrations\n"
,
isSelected
:
this
.
isSelect
!
})
?
SettingDetails
({
image
:
"common/images/ic_highlight.png"
,
title
:
"Light\nControl"
,
isSelected
:
this
.
isSelect
!
})
?
}
Row
() {
SettingDetails
({
image
:
"common/images/opacity.png"
,
title
:
"Leak\nDetector"
,
isSelected
:
this
.
isSelect
!
})
SettingDetails
({
image
:
"common/images/ac_unit.png"
,
title
:
"Temperature\nControl"
,
isSelected
:
this
.
isSelect
!
})
SettingDetails
({
image
:
"common/images/key.png"
,
title
:
"Guest\nAccess"
,
isSelected
:
this
.
isSelect
!
})
?
?
}
Button
(
"NEXT"
)
.
fontSize
(
60
)
.
fontColor
(
Color
.
Black
)
.
width
(
600
)
.
height
(
100
)
.
backgroundColor
(
Color
.
Red
)
.
margin
({
top
:
100
})
.
onClick
(()
=>
{
router
.
push
({
url
:
'pages/SensorScreen'
})
})
}
.
width
(
'100%'
)
?
.
height
(
'100%'
).
backgroundColor
(
"#F5F5F5"
)
}
}
針對這一頁:首先是頭部
代碼如下:
Row() {
?
Image($r("app.media.logo"))
.objectFit(ImageFit.Contain)
.width(200)
.height(200)
.borderRadius(21)
?
Column() {
Text('June 14, 2022')
.fontSize(40).opacity(0.4)
.fontWeight(FontWeight.Bold)
Text('Good Morning,\nJianGuo',)
.fontSize(60)
.fontWeight(FontWeight.Bold)
}
?
?
}
其次是個人信息,包括頭像等信息:
代碼如下:
?
接下來就是溫度和濕度
代碼如下:
ow
({
space
:
120
}) {
Column
() {
Text
(
'40°'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'TEMPERATURE'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
}.
margin
({
left
:
60
})
?
Column
() {
Text
(
'59%'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'HUMIDITY'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
}.
margin
({
right
:
60
})
}.
margin
({
top
:
20
})
SensorScreen.ets
import
{
HomeDetails
}
from
'./common/homedetails'
;
// second.ets
import
router
from
'@ohos.router'
;
?
@
Entry
@
Component
struct
Second
{
@
State
message
:
string
=
'Hi there'
@
State
private
isSelect
:
boolean
=
true
;
?
build
() {
?
Column
() {
Row
() {
?
Image
(
$r
(
"app.media.back"
))
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
80
)
.
height
(
80
)
.
onClick
(()
=>
{
router
.
back
()
})
?
Blank
()
?
Text
(
'Home'
)
.
fontSize
(
45
)
.
fontWeight
(
FontWeight
.
Bold
)
?
?
Blank
()
Image
(
$r
(
"app.media.notifications_none"
))
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
80
)
.
height
(
80
)
.
onClick
(()
=>
{
router
.
back
()
})
?
}
?
.
width
(
'100%'
)
?
Row
() {
?
Image
(
$r
(
"app.media.logo"
))
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
200
)
.
height
(
200
)
.
borderRadius
(
21
)
?
Column
() {
Text
(
'June 14, 2022'
)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'Good Morning,\nJianGuo'
,)
.
fontSize
(
60
)
.
fontWeight
(
FontWeight
.
Bold
)
}
?
?
}
?
Row
({
space
:
120
}) {
Column
() {
Text
(
'40°'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'TEMPERATURE'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
}.
margin
({
left
:
60
})
?
Column
() {
Text
(
'59%'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'HUMIDITY'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
}.
margin
({
right
:
60
})
}.
margin
({
top
:
20
})
?
?
Row
() {
HomeDetails
({})
?
HomeDetails
({
image
:
"common/images/lightbull.png"
,
isSelected
:
this
.
isSelect
!
})
?
}
?
Row
() {
?
?
HomeDetails
({
image
:
"common/images/opacity.png"
})
HomeDetails
({
image
:
"common/images/yytem0.png"
})
?
?
}
?
Row
(){
Column
(){
Text
(
'ADD'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
.
fontWeight
(
FontWeight
.
Bold
)
Text
(
'NEW CONTROL'
,)
.
fontSize
(
40
).
opacity
(
0.4
)
}
Blank
()
?
Image
(
$r
(
"app.media.add"
))
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
100
)
.
height
(
100
)
.
borderRadius
(
21
).
margin
({
right
:
40
})
?
}.
border
({
color
:
Color
.
White
,
width
:
8
,
radius
:
20
}).
width
(
"88%"
).
height
(
150
)
?
}.
width
(
"100%"
)
.
height
(
'100%'
).
backgroundColor
(
"#F5F5F5"
)
}
}
我們可以對,下面的這塊進行封裝
代碼如下
@
Entry
@
Component
export
struct
SettingDetails
{
@
State
private
image
:
string
=
"common/images/setting.png"
@
State
private
title
:
string
=
"Maintenance\nRequests"
@
State
private
isSelected
:
boolean
=
true
;
?
build
() {
?
?
Column
() {
Image
(
this
.
image
)
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
140
)
.
height
(
120
)
.
margin
(
20
)
.
border
({
width
:
12
,
color
:
this
.
isSelected
?
Color
.
White
:
Color
.
Red
,
radius
:
20
})
.
onClick
(()
=>
{
this
.
isSelected
=
!
this
.
isSelected
;
})
Text
(
this
.
title
).
fontSize
(
32
).
width
(
200
).
textAlign
(
TextAlign
.
Center
)
}
}}
我們可以對,下面的這塊進行封裝
代碼如下
@
Entry
@
Component
export
struct
SettingDetails
{
@
State
private
image
:
string
=
"common/images/setting.png"
@
State
private
title
:
string
=
"Maintenance\nRequests"
@
State
private
isSelected
:
boolean
=
true
;
?
build
() {
?
?
Column
() {
Image
(
this
.
image
)
.
objectFit
(
ImageFit
.
Contain
)
.
width
(
140
)
.
height
(
120
)
.
margin
(
20
)
.
border
({
width
:
12
,
color
:
this
.
isSelected
?
Color
.
White
:
Color
.
Red
,
radius
:
20
})
.
onClick
(()
=>
{
this
.
isSelected
=
!
this
.
isSelected
;
})
Text
(
this
.
title
).
fontSize
(
32
).
width
(
200
).
textAlign
(
TextAlign
.
Center
)
}
}}
最后就是底部
代碼如下:
Row(){
Column(){
Text('ADD',)
.fontSize(40).opacity(0.4)
.fontWeight(FontWeight.Bold)
Text('NEW CONTROL',)
.fontSize(40).opacity(0.4)
}
Blank()
Image($r("app.media.add"))
.objectFit(ImageFit.Contain)
.width(100)
.height(100)
.borderRadius(21).margin({right:40})
}.border({
color:Color.White,
width:8,
radius:20
}).width("88%").height(150)
恭喜你
在本文中,通過實現智聯汽車App示例,我主要為大家講解了如下ArkUI(基于TS擴展的類Web開發范式)組件,以及路由跳轉。
容器組件
Column
Row
Stack
基礎組件
Text
Button
Image
Navigation
通用
邊框設置
尺寸設置
點擊控制
布局約束
背景設置
點擊事件
TS語法糖
希望通過本教程,各位開發者可以對以上基礎組件具有更深刻的認識。
后面的計劃:
智能互聯
硬件交互
動畫交互
-
智能家居
+關注
關注
1928文章
9581瀏覽量
185592 -
HarmonyOS
+關注
關注
79文章
1980瀏覽量
30290 -
OpenHarmony
+關注
關注
25文章
3729瀏覽量
16407
發布評論請先 登錄
相關推薦
評論