新聞中心
以下根據(jù)實(shí)際的開(kāi)發(fā)樣例來(lái)展示如何在已有的 HarmonyOS 工程中添加一個(gè)智能穿戴模塊。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括張家港網(wǎng)站建設(shè)、張家港網(wǎng)站制作、張家港網(wǎng)頁(yè)制作以及張家港網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,張家港網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到張家港省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
如圖所示,這是一個(gè)睡眠檢測(cè)應(yīng)用,應(yīng)用分為主界面和詳情界面,可以選擇使用 PageSlider 實(shí)現(xiàn)界面間的切換。PageSlider 是一個(gè)布局管理器,用于實(shí)現(xiàn)左右滑動(dòng)以及上下滑動(dòng)的翻頁(yè)效果。
圖1 開(kāi)發(fā)樣例效果圖
- 在 DevEco Studio 上方的導(dǎo)航欄中,依次點(diǎn)擊“File > New > Module”,在“Device”中選擇“Wearable”,添加一個(gè)新模塊。
- 在左側(cè)的“Project”窗口,打開(kāi)“entry > src > main > resources > base”,右鍵點(diǎn)擊“base”文件夾,選擇“New > Directory”,命名為“l(fā)ayout”。
- 右鍵點(diǎn)擊“l(fā)ayout”文件夾,選擇“New > File”,新建兩個(gè)UI布局文件,分別命名為“l(fā)ayout_sleep.xml”和“l(fā)ayout_detail.xml”。
主界面的UI布局文件是“l(fā)ayout_sleep.xml”,其完整示例代碼如下:
詳情界面的 UI 布局文件是“l(fā)ayout_detail.xml”,其完整示例代碼如下:
- 在左側(cè)項(xiàng)目文件欄中,選擇“entry > src > main > java > 應(yīng)用包名 > slice”,在對(duì)應(yīng)的 AbilitySlice 文件的 onStart 里,使用代碼創(chuàng)建 PageSlider,添加這兩個(gè)相應(yīng)的界面。
public class SleepPageSlice extends AbilitySlice {
private static final String TAG = "SleepPageSlice";
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, TAG);
private List list = new ArrayList<>();
private PageSliderProvider provider = new PageSliderProvider() {
@Override
public int getCount() {
return list.size();
}
@Override
public Object createPageInContainer(ComponentContainer componentContainer, int index) {
if (index >= list.size() || componentContainer == null) {
HiLog.error(LABEL, "instantiateItem index error");
return Optional.empty();
}
ComponentOwner container = list.get(index);
componentContainer.addComponent(container.getComponent());
container.instantiateComponent();
return container.getComponent();
}
@Override
public void destroyPageFromContainer(ComponentContainer componentContainer, int index, Object object) {
HiLog.info(LABEL, "destroyItem index:" + index);
if (index >= list.size() || componentContainer == null) {
return;
}
Component content = list.get(index).getComponent();
componentContainer.removeComponent(content);
return;
}
@Override
public boolean isPageMatchToObject(Component component, Object object) {
return component == object;
}
@Override
public void startUpdate(ComponentContainer container) {
super.startUpdate(container);
HiLog.info(LABEL, "startUpdate");
}
};
@Override
public void onStart(Intent intent) {
super.onStart(intent);
HiLog.info(LABEL, "onStart");
// 添加子頁(yè)面
list.add(new SleepComponentOwner(this));
list.add(new DetailComponentOwner(this));
// 設(shè)置主界面
DirectionalLayout layout = new DirectionalLayout(this);
ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT,
ComponentContainer.LayoutConfig.MATCH_PARENT);
layout.setLayoutConfig(config);
// 使用PageSlider做滑動(dòng)效果
PageSlider slider = new PageSlider(this);
ComponentContainer.LayoutConfig sliderConfig = new ComponentContainer.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT,
ComponentContainer.LayoutConfig.MATCH_PARENT);
slider.setLayoutConfig(sliderConfig);
slider.setOrientation(DirectionalLayout.VERTICAL);
slider.setProvider(provider);
layout.addComponent(slider);
setUIContent(layout);
}
}
- 增加 ComponentOwner 容器接口和兩個(gè)頁(yè)面的實(shí)現(xiàn)方式,如下是容器的接口 ComponentOwner.java。
public interface ComponentOwner {
// 獲取存放的component
Component getComponent();
// 當(dāng)包含的component被添加到容器時(shí)回調(diào)
void instantiateComponent();
}
- 增加第一個(gè)頁(yè)面 SleepComponentOwner 和第二個(gè)頁(yè)面 DetailComponentOwner,這兩個(gè)頁(yè)面從 xml 里加載。以下是首頁(yè) SleepComponentOwner 的實(shí)現(xiàn)。
public class SleepComponentOwner implements ComponentOwner {
private static final String TAG = "SleepViewContainer";
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, TAG);
// 目標(biāo)睡眠時(shí)長(zhǎng)默認(rèn)值,單位:分鐘
private static final int DEFAULT_SLEEP_TARGET_TIME = 480;
// 睡眠時(shí)長(zhǎng)默認(rèn)值,單位:分鐘
private static final int DEFAULT_SLEEP_TIME = 0;
private CircleProgressDrawTask drawTask;
private AbilityContext myContext;
private Component root;
public SleepComponentOwner(AbilityContext context) {
init(context);
}
private void init(AbilityContext context) {
myContext = context;
LayoutScatter scatter = LayoutScatter.getInstance(context);
root = scatter.parse(ResourceTable.Layout_layout_sleep, null, false);
drawTask = new CircleProgressDrawTask(root);
drawTask.setMaxValue(DEFAULT_SLEEP_TARGET_TIME);
Component imageView = root.findComponentById(ResourceTable.Id_sleep_moon_img);
imageView.setBackground(new VectorElement(context, ResourceTable.Graphic_ic_icon_moon));
}
@Override
public Component getComponent() {
return root;
}
@Override
public void instantiateComponent() {
return;
}
}
以下是第二個(gè)頁(yè)面 DetailComponentOwner 的實(shí)現(xiàn)。
public class DetailComponentOwner implements ComponentOwner {
private static final String TAG = "DetailViewContainer";
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, TAG);
private AbilityContext myContext;
private ComponentContainer root;
public DetailComponentOwner(AbilityContext context) {
init(context);
}
private void init(AbilityContext context) {
root = new DirectionalLayout(context);
ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT,
ComponentContainer.LayoutConfig.MATCH_PARENT);
root.setLayoutConfig(config);
myContext = context;
}
@Override
public Component getComponent() {
return root;
}
@Override
public void instantiateComponent() {
return;
}
}
- 增加一個(gè)類型為Page的Ability,并在config.json里進(jìn)行注冊(cè)。需要在onStart里調(diào)用setSwipeToDismiss(true),來(lái)設(shè)置右滑退出。示例代碼如下:
public class PageAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(SleepPageSlice.class.getName());
setSwipeToDismiss(true);
}
}
如下是配置文件 config.json,注冊(cè) PageAbility的時(shí)候,需要指明 action.system.home,用來(lái)保證該 Ability 能在 launcher 上顯示對(duì)應(yīng)的圖標(biāo)。
{
"app": {
"bundleName": "com.huawei.health.sleep",
"vendor": "huawei",
"version": {
"code": 1,
"name": "1.0.8.27"
},
"apiVersion: {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {
"default": {
}
}
},
"module": {
"package": "com.huawei.health.sleep",
"name": ".SleepApplication",
"distro": {
"moduleType": "entry",
"deliveryWithInstall": true,
"moduleName": "entry"
},
"deviceType": [
"wearable"
],
"reqCapabilities": [
"video_support"
],
"abilities": [
{
"name": ".PageAbility",
"description": "$string:ability_description",
"icon": "$media:icon_app",
"label": "$string:app_name",
"launchType": "standard",
"orientation": "portrait",
"visible": true,
"permissions": [],
"skills": [
{
"actions": [
"action.system.home"
],
"entities": [
"entity.system.home"
],
}
],
"type": "page",
"formEnabled": false
}
]
}
}
在睡眠界面中,我們用到了圓環(huán)效果,這里我們看一下圓環(huán)效果是如何實(shí)現(xiàn)的,如何實(shí)現(xiàn)自定義 Component 的效果。調(diào)用方代碼如下:
drawTask = new CircleProgressDrawTask(root);
Componet 類提供了 UI 的基本組件,包括方法addDrawTask(Component.DrawTask task)。該方法可以給任意一個(gè)Componet 添加一段自定義繪制的代碼。自定義 Component 的實(shí)現(xiàn)方法如下:
- 創(chuàng)建一個(gè)自定義 DrawTask,包含與該 Componet 相關(guān)的自定義屬性和繪制的代碼。
- 在構(gòu)造方法里傳入宿主 Component,跟自定義的 DrawTask 綁定。
實(shí)現(xiàn)睡眠圓環(huán)效果的示例代碼如下。
public class CircleProgressDrawTask implements Component.DrawTask {
// 用于配置圓環(huán)的粗細(xì),具體參數(shù)可以在xml文件中配置
private static final String STROKE_WIDTH_KEY = "stroke_width";
// 用于配置圓環(huán)的最大值,具體參數(shù)可以在xml文件中配置
private static final String MAX_PROGRESS_KEY = "max_progress";
// 用于配置圓環(huán)的當(dāng)前值,具體參數(shù)可以在xml文件中配置
private static final String CURRENT_PROGRESS_KEY = "current_progress";
// 用于配置起始位置的顏色,具體參數(shù)可以在xml文件中配置
private static final String START_COLOR_KEY = "start_color";
// 用于配置結(jié)束位置的顏色,具體參數(shù)可以在xml文件中配置
private static final String END_COLOR_KEY = "end_color";
// 用于配置背景色,具體參數(shù)可以在xml文件中配置
private static final String BACKGROUND_COLOR_KEY = "background_color";
// 用于配置起始位置的角度,具體參數(shù)可以在xml文件中配置
private static final String START_ANGLE = "start_angle";
private static final float MAX_ARC = 360f;
private static final int DEFAULT_STROKE_WIDTH = 10;
private static final int DEFAULT_MAX_VALUE = 100;
private static final int DEFAULT_START_COLOR = 0xFFB566FF;
private static final int DEFAULT_END_COLOR = 0xFF8A2BE2;
private static final int DEFAULT_BACKGROUND_COLOR = 0xA8FFFFFF;
private static final int DEFAULT_START_ANGLE = -90;
private static final float DEFAULT_LINER_MAX = 100f;
private static final int HALF = 2;
// 圓環(huán)的寬度, 默認(rèn)10個(gè)像素
private int myStrokeWidth = DEFAULT_STROKE_WIDTH;
// 最大的進(jìn)度值, 默認(rèn)是100
private int myMaxValue = DEFAULT_MAX_VALUE;
// 當(dāng)前的進(jìn)度值, 默認(rèn)是0
private int myCurrentValue = 0;
// 起始位置的顏色, 默認(rèn)淺紫色
private Color myStartColor = new Color(DEFAULT_START_COLOR);
// 結(jié)束位置的顏色, 默認(rèn)深紫色
private Color myEndColor = new Color(DEFAULT_END_COLOR);
// 背景顏色, 默認(rèn)淺灰色
private Color myBackgroundColor = new Color(DEFAULT_BACKGROUND_COLOR);
// 當(dāng)前的進(jìn)度值, 默認(rèn)從-90度進(jìn)行繪制
private int myStartAngle = DEFAULT_START_ANGLE;
private Component myComponent;
// 傳入要進(jìn)行修改的component
public CircleProgressDrawTask(Component component) {
myComponent = component;
myComponent.addDrawTask(this);
}
// 設(shè)置當(dāng)前進(jìn)度并且刷新component,value值為當(dāng)前進(jìn)度
public void setValue(int value) {
myCurrentValue = value;
myComponent.invalidate();
}
public void setMaxValue(int maxValue) {
myMaxValue = maxValue;
myComponent.invalidate();
}
@Override
public void onDraw(Component component, Canvas canvas) {
// 通過(guò)canvas實(shí)現(xiàn)繪制圓環(huán)的功能
......
}
}
網(wǎng)站題目:創(chuàng)新互聯(lián)鴻蒙OS教程:鴻蒙OS添加智能穿戴模塊
地址分享:http://m.fisionsoft.com.cn/article/ccodeoe.html


咨詢
建站咨詢
