The promt.showDialog API of Quick App can be used to implement simple pop-up elements such as text and buttons, but cannot achieve complex display effects. UI designers will often design complex effects, so how do we actually achieve them as engineers?
For example, the design of a pop-up includes a list, in which images are displayed on the left and descriptions need to be shown on the right, as shown in Figure 1 below. Another pop-up instructs users to check the app’s privacy statement via a link, as shown in Figure 2.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Figure 1 Pop-up with a list Figure 2 Pop-up with a link
Proper arrangement of quick app elements and style attributes can help achieve such complex effects.
SolutionYou can use the stack element with the position: fixed CSS style to implement a custom pop-up. Whether to display the pop-up can be determined using the if/show command. Sample code is as follows:
1.Initialize data models:
HTML:
data() {
return {
list: [1, 2, 3],
isShow: false,
ifShow1: false,
ifShow2: false
}
},
2.Page layout:
HTML:
<text onclick="showToast1">Custom pop-up window 1</text>
<text onclick="showToast2">Custom pop-up window 2</text>
<!-- Pop-up window -->
<div if="{{isShow}}" class="modal center-modal">
<div class="toast-box password-box">
<block>
<stack>
<div style="flex-direction: column;width: 100%;" if="{{ifShow1}}">
<div style="width: 100%;">
<text style="font-size: 32px;font-weight: 500;">Traffic violation</text>
<text style="font-size: 25px;text-align: right;padding-left: 400px" onclick="hide">Hide</text>
</div>
<list style="height: 550px">
<list-item type="list" for="list" style="height: 160px;margin-top: 20px">
<div style="padding-top: 1px;">
<image src="/Common/icon.png" style="border-radius: 100%;width: 100px;height: 100px;"></image>
<div style="flex-direction: column; margin-left: 20px">
<text style="font-size: 28px;font-weight: 600;">Level-2 title</text>
<text style="font-size: 26px;margin-top: 10px">Displaying product attributes, prices, release dates, and more.</text>
<div style="height: 2px;background-color:#808080;bottom: 0;margin-top: 25px" if="{{$idx<2}}">
</div>
</div>
</div>
</list-item>
</list>
</div>
<div style="flex-direction: column;width: 100%;" if="{{ifShow2}}">
<text style="font-size: 31px;font-weight: 700;">City services</text>
<text style="font-weight: 400;"><span>By tapping Agree, you agree to the above terms as well as the </span><a style="color: #0000ff;" onclick="toast">XX User Agreement</a>
<span> and </span><a style="color: #0000ff;" onclick="toast">Privacy Statement About XX.</a></text>
<div style="width: 100%;">
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">OK</text>
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">Cancel</text>
</div>
</div>
</stack>
</block>
</div>
</div>
Page style:
CSS:
.container {
flex-direction: column;
justify-content: center;
align-items: center;
.body {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
.img {
margin-top: 500px;
}
.txt {
margin-top: 570px;
}
}
// Pop-up style
.modal {
position: fixed;
flex-direction: column;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 0 34px 34px;
background-color: rgba(0, 0, 0, 0.18);
animation-name: Modal;
animation-duration: 130ms;
animation-timing-function: ease-in;
.toast-box {
width: 100%;
padding: 25px 50px 20.8px;
border-radius: 34px;
background-color: white;
flex-direction: column;
.toast-title {
font-size: 41.6px;
line-height: 56px;
font-weight: 500;
font-family: HWtext-65ST;
color: #000000;
}
.toast-tip {
font-family: HWtext-55ST;
font-size: 29px;
color: rgba(0, 0, 0, 0.6);
line-height: 40px;
margin-top: 3.6px;
margin-bottom: 25px;
}
.label-box {
height: 100px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
.label {
color: #000000;
width: 100%;
font-family: HWtext-55ST;
font-size: 34px;
}
input {
margin-right: -11px;
}
}
.manage {
height: 100px;
font-family: HWtext-65ST;
font-size: 29.12px;
color: #007dff;
font-weight: 500;
}
.cancel {
width: 100%;
height: 75px;
margin-top: 37.44px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
font-weight: 500;
}
.btn-box {
justify-content: space-between;
align-items: center;
.bind {
width: 47%;
height: 60px;
border-radius: 10px;
font-family: HWtext-65ST;
text-align: center;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.line {
height: 50px;
width: 1px;
background-color: rgba(0, 0, 0, 0.2);
}
.quit {
width: 47%;
height: 60px;
border-radius: 10px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.bind:active {
background-color: rgba(0, 0, 0, 0.1); // To be modified in the high-fidelity design.
}
.quit:active {
background-color: rgba(0, 0, 0, 0.1); // To be modified in the high-fidelity design.
}
}
.nocar-tip {
height: 99.84px;
font-size: 33.28px;
font-family: HWtext-55ST;
color: #000000;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
}
.password-box {
margin-top: -110px;
padding: 30.63px 50px 20.8px;
.toast-title {
height: 55.64px;
margin-bottom: 30.12px;
}
.password-tip {
flex-direction: column;
margin-top: 3.6px;
margin-bottom: 25px;
.control-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: rgba(0, 0, 0, 0.6);
}
}
.error-password-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: #fa2a2d;
height: 32.76px;
margin-bottom: 37.4px;
margin-top: 0;
}
.btn-box {
.bind {
margin-top: 8px;
margin-bottom: 8px;
}
.quit {
margin-top: 8px;
margin-bottom: 8px;
}
}
.eyes-input-box {
width: 100%;
flex-direction: row;
justify-content: flex-end;
.input-password {
width: 100%;
height: 94.64px;
border: 1px solid #ffffff;
border-bottom-color: #000000;
padding: 11.44px 0;
margin-bottom: 20.8px;
}
.password-text {
width: 100%;
height: 94.64px;
padding: 11.44px 0;
border-bottom: 1px solid #000000;
margin-bottom: 20.8px;
color: #000000;
font-size: 36px;
}
.eyes-img {
width: 49.92px;
height: 49.92px;
margin-top: 23px;
}
}
.password-loading-box {
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 150px;
.loading-text {
font-family: HWtext-55ST;
font-size: 33.28px;
color: rgba(0, 0, 0, 0.96);
}
.loading-circular {
width: 102px;
height: 102px;
color: #666666;
}
}
}
}
}
For more information,please refer to the following:
Style of Quick App
Quick App materials
Common settings of Quick App
Is it supports in Xamarin?
ask011 said:
Is it supports in Xamarin?
Click to expand...
Click to collapse
Sorry. It supported in quick app. It is different from Xamarin. If you want to implement custom pop up in xamarin, you can try to study other tutorials perhaps.
Hope it works for Hormony os as well.
shikkerimath said:
Hope it works for Hormony os as well.
Click to expand...
Click to collapse
The JS UI framework supports custom components for you to extend existing components based on your application services. you can implement by following the document.
Related
xxxxxxxxxxxxxxxx
[deleted]
@mods: Please close or even better delete!
.wysiwyg { background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; background-color: #ffffcc; background-image: none; color: #000000; font-family: Verdana, Arial, Arial; font-style: normal; font-variant: normal; font-weight: 400; font-size: 10pt; line-height: normal } p { margin: 0px; }
yep, sorry, deleted my post.
You can run the if/show command to control the display of a pop-up window based on the stack component and the position:fixed CSS file. The following code implements two custom pop-up windows:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
1. Initialize data models.
data() {
return {
list: [1, 2, 3],
isShow: false,
ifShow1: false,
ifShow2: false
}
},
2. Set the page layout.
<text onclick="showToast1">Custom pop-up window 1</text>
<text onclick="showToast2">Custom pop-up window 2</text>
<!-- Pop-up window -->
<div if="{{isShow}}" class="modal center-modal">
<div class="toast-box password-box">
<block>
<stack>
<div style="flex-direction: column;width: 100%;" if="{{ifShow1}}">
<div style="width: 100%;">
<text style="font-size: 32px;font-weight: 500;">Traffic violation</text>
<text style="font-size: 25px;text-align: right;padding-left: 400px" onclick="hide">Hide</text>
</div>
<list style="height: 550px">
<list-item type="list" for="list" style="height: 160px;margin-top: 20px">
<div style="padding-top: 1px;">
<image src="/Common/icon.png" style="border-radius: 100%;width: 100px;height: 100px;"></image>
<div style="flex-direction: column; margin-left: 20px">
<text style="font-size: 28px;font-weight: 600;">Level-2 title</text>
<text style="font-size: 26px;margin-top: 10px">Displaying product attributes, prices, release dates, and more.</text>
<div style="height: 2px;background-color:#808080;bottom: 0;margin-top: 25px" if="{{$idx<2}}">
</div>
</div>
</div>
</list-item>
</list>
</div>
<div style="flex-direction: column;width: 100%;" if="{{ifShow2}}">
<text style="font-size: 31px;font-weight: 700;">City services</text>
<text style="font-weight: 400;"><span>By tapping Agree, you agree to the above terms as well as the </span><a style="color: #0000ff;" onclick="toast">XX User Agreement</a>
<span> and </span><a style="color: #0000ff;" onclick="toast">Privacy Statement About XX.</a></text>
<div style="width: 100%;">
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">OK</text>
<text style="width: 50%; text-align: center; color: #0000ff;" onclick="hide">Cancel</text>
</div>
</div>
</stack>
</block>
</div>
</div>
3. Set the page style.
.container {
flex-direction: column;
justify-content: center;
align-items: center;
.body {
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
.img {
margin-top: 500px;
}
.txt {
margin-top: 570px;
}
}
// Pop-up window style.
.modal {
position: fixed;
flex-direction: column;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 0 34px 34px;
background-color: rgba(0, 0, 0, 0.18);
animation-name: Modal;
animation-duration: 130ms;
animation-timing-function: ease-in;
.toast-box {
width: 100%;
padding: 25px 50px 20.8px;
border-radius: 34px;
background-color: white;
flex-direction: column;
.toast-title {
font-size: 41.6px;
line-height: 56px;
font-weight: 500;
font-family: HWtext-65ST;
color: #000000;
}
.toast-tip {
font-family: HWtext-55ST;
font-size: 29px;
color: rgba(0, 0, 0, 0.6);
line-height: 40px;
margin-top: 3.6px;
margin-bottom: 25px;
}
.label-box {
height: 100px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
.label {
color: #000000;
width: 100%;
font-family: HWtext-55ST;
font-size: 34px;
}
input {
margin-right: -11px;
}
}
.manage {
height: 100px;
font-family: HWtext-65ST;
font-size: 29.12px;
color: #007dff;
font-weight: 500;
}
.cancel {
width: 100%;
height: 75px;
margin-top: 37.44px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
font-weight: 500;
}
.btn-box {
justify-content: space-between;
align-items: center;
.bind {
width: 47%;
height: 60px;
border-radius: 10px;
font-family: HWtext-65ST;
text-align: center;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.line {
height: 50px;
width: 1px;
background-color: rgba(0, 0, 0, 0.2);
}
.quit {
width: 47%;
height: 60px;
border-radius: 10px;
text-align: center;
font-family: HWtext-65ST;
font-size: 33.28px;
color: #007dff;
margin: 16px 0;
font-weight: 500;
}
.bind:active {
background-color: rgba(0, 0, 0, 0.1);
}
.quit:active {
background-color: rgba(0, 0, 0, 0.1);
}
}
.nocar-tip {
height: 99.84px;
font-size: 33.28px;
font-family: HWtext-55ST;
color: #000000;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
}
.password-box {
margin-top: -110px;
padding: 30.63px 50px 20.8px;
.toast-title {
height: 55.64px;
margin-bottom: 30.12px;
}
.password-tip {
flex-direction: column;
margin-top: 3.6px;
margin-bottom: 25px;
.control-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: rgba(0, 0, 0, 0.6);
}
}
.error-password-tip {
font-family: HWtext-55ST;
font-size: 24.96px;
color: #fa2a2d;
height: 32.76px;
margin-bottom: 37.4px;
margin-top: 0;
}
.btn-box {
.bind {
margin-top: 8px;
margin-bottom: 8px;
}
.quit {
margin-top: 8px;
margin-bottom: 8px;
}
}
.eyes-input-box {
width: 100%;
flex-direction: row;
justify-content: flex-end;
.input-password {
width: 100%;
height: 94.64px;
border: 1px solid #ffffff;
border-bottom-color: #000000;
padding: 11.44px 0;
margin-bottom: 20.8px;
}
.password-text {
width: 100%;
height: 94.64px;
padding: 11.44px 0;
border-bottom: 1px solid #000000;
margin-bottom: 20.8px;bind:active {
color: #000000;
font-size: 36px;
}
.eyes-img {
width: 49.92px;
height: 49.92px;
margin-top: 23px;
}
}
.password-loading-box {
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 150px;
.loading-text {
font-family: HWtext-55ST;
font-size: 33.28px;
color: rgba(0, 0, 0, 0.96);
}
.loading-circular {
width: 102px;
height: 102px;
color: #666666;
}
}
}
}
}
4. Bind an event.
showToast1() {
this.isShow = true;
this.ifShow1 = true
this.ifShow2 = false
},
showToast2() {
this.isShow = true;
this.ifShow1 = false
this.ifShow2 = true
},
hide(){
this.isShow = false;
},
toast() {
prompt.showToast({
message: 'View privacy agreement'
})
}
How can I read the global variables defined in app.ux from a JavaScript file?
For example, You can define the variable AppData in app.ux.
data: {
AppData: '123456',
}
The code in the JavaScript file is as follows:
export default {
getAppData() {
return getApp().$def.data.AppData
}
}
For more information, please refer to the Common methods section in Script.
Article Introduction
In this article, I have explained to develop a calculator application for Huawei Lite Wearable device using Huawei DevEco Studio and using JS language in Harmony OS. Calculator here performs basic arithmetic operations which can be installed in wearable watch.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Huawei Lite Wearable
Requirements
1) DevEco IDE
2) Lite wearable watch (Can use simulator also)
New Project (Lite Wearable)
After installation of DevEco Studio, make new project.
Select Lite Wearable in Device and select Empty Feature Ability in Template.
After the project is created, its directory as shown in below displayed image.
hml files describe the page layout.
css files describe the page style.
js files process the interactions between pages and users.
The app.js file manages global JavaScript logics and application lifecycle.
The pages directory stores all component pages.
The common directory stores public resource files, such as media resources and .js files.
Integration process
Design the UI
Step 1: Add background image.
As the first step, we can create a UI that contains keypads with all number keys, operator keys and result display text box.
Create and add the background image for calculator screen using stack component.
index.html
Code:
<stack class="stack">
<image src='/common/watchbackground.png' class="background"></image>
</stack>
index.css
Code:
.stack {
width: 454px;
height: 454px;
justify-content: center;
}
Step 2: Add keys UI in the keypad
Create and add rows of the keys for keypad. Numbers 0-9, “.” And equal key for calculating operation.
Code:
<div class="calcRow">
<text class="numberBtn" value="7" onclick="handleNumber(7)"></text>
<text class="numberBtn" value="8" onclick="handleNumber(8)"></text>
<text class="numberBtn" value="9" onclick="handleNumber(9)"></text>
<text class="equalBtn" value=" "></text>
</div>
<div class="calcRow">
<text class="numberBtn" value="4" onclick="handleNumber(4)"></text>
<text class="numberBtn" value="5" onclick="handleNumber(5)"></text>
<text class="numberBtn" value="6" onclick="handleNumber(6)"></text>
<text class="equalBtn" value="=" onclick="handlecalculate"></text>
</div>
<div class="calcRow">
<text class="numberBtn" value="1" onclick="handleNumber(1)"></text>
<text class="numberBtn" value="2" onclick="handleNumber(2)"></text>
<text class="numberBtn" value="3" onclick="handleNumber(3)"></text>
<text class="equalBtn" value=" "></text>
</div>
Code:
.calcRow {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 454px;
height: 50px;
background-color: transparent;
}
.equalBtn {
display: flex;
text-align: center;
width: 75px;
height: 50px;
border-width: 0px;
border-color: #414343;
color: #414343;
background-color: #f87d4f;
}.numberBtn {
display: flex;
text-align: center;
width: 75px;
height: 50px;
border-width: 1px;
color: #414343;
background-color: #ffffff;
border-color: #414343;
border-radius: 5px;
}
For more, you can check https://forums.developer.huawei.com/forumPortal/en/topic/0201459032942010032
John Wo said:
Article Introduction
In this article, I have explained to develop a calculator application for Huawei Lite Wearable device using Huawei DevEco Studio and using JS language in Harmony OS. Calculator here performs basic arithmetic operations which can be installed in wearable watch.
Huawei Lite Wearable
Requirements
1) DevEco IDE
2) Lite wearable watch (Can use simulator also)
New Project (Lite Wearable)
After installation of DevEco Studio, make new project.
Select Lite Wearable in Device and select Empty Feature Ability in Template.
After the project is created, its directory as shown in below displayed image.
hml files describe the page layout.
css files describe the page style.
js files process the interactions between pages and users.
The app.js file manages global JavaScript logics and application lifecycle.
The pages directory stores all component pages.
The common directory stores public resource files, such as media resources and .js files.
Integration process
Design the UI
Step 1: Add background image.
As the first step, we can create a UI that contains keypads with all number keys, operator keys and result display text box.
Create and add the background image for calculator screen using stack component.
index.html
Code:
<stack class="stack">
<image src='/common/watchbackground.png' class="background"></image>
</stack>
index.css
Code:
.stack {
width: 454px;
height: 454px;
justify-content: center;
}
Step 2: Add keys UI in the keypad
Create and add rows of the keys for keypad. Numbers 0-9, “.” And equal key for calculating operation.
Code:
<div class="calcRow">
<text class="numberBtn" value="7" onclick="handleNumber(7)"></text>
<text class="numberBtn" value="8" onclick="handleNumber(8)"></text>
<text class="numberBtn" value="9" onclick="handleNumber(9)"></text>
<text class="equalBtn" value=" "></text>
</div>
<div class="calcRow">
<text class="numberBtn" value="4" onclick="handleNumber(4)"></text>
<text class="numberBtn" value="5" onclick="handleNumber(5)"></text>
<text class="numberBtn" value="6" onclick="handleNumber(6)"></text>
<text class="equalBtn" value="=" onclick="handlecalculate"></text>
</div>
<div class="calcRow">
<text class="numberBtn" value="1" onclick="handleNumber(1)"></text>
<text class="numberBtn" value="2" onclick="handleNumber(2)"></text>
<text class="numberBtn" value="3" onclick="handleNumber(3)"></text>
<text class="equalBtn" value=" "></text>
</div>
Code:
.calcRow {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 454px;
height: 50px;
background-color: transparent;
}
.equalBtn {
display: flex;
text-align: center;
width: 75px;
height: 50px;
border-width: 0px;
border-color: #414343;
color: #414343;
background-color: #f87d4f;
}.numberBtn {
display: flex;
text-align: center;
width: 75px;
height: 50px;
border-width: 1px;
color: #414343;
background-color: #ffffff;
border-color: #414343;
border-radius: 5px;
}
For more, you can check https://forums.developer.huawei.com/forumPortal/en/topic/0201459032942010032
Click to expand...
Click to collapse
can we use java language for Lite variable
Introduction
Harmony OS is a future-proof distributed operating system open to you as part of the initiatives for all-scenario strategy, adaptable to mobile office, fitness and health, social communication, and media entertainment, to name a few. Unlike a legacy operating system that runs on a standalone device, Harmony OS is built on a distributed architecture designed based on a set of system capabilities. It can run on a wide range of device forms, including smartphones, tablets, wearables, smart TVs and head units.
In this article, we will create simple Lite wearable JS application to control the brightness of wearable.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Requirements
1) DevEco IDE
2) Lite wearable simulator
Implementation
First page, index.hml contains basic UI component showing list of predefined brightness values in percentage.
HTML:
<div class="container">
<image class= "image" src='/common/brightness_control.png' ></image>
<text class="title">
Brightness Control
</text>
<list class="showList">
<list-item class="showListItem" for="{{(index, value) in listData}}" tid="id">
<text class="content" onclick="onItemClick(value)">
{{value}}
</text>
<div class="divider"></div>
</list-item>
</list>
</div>
Here, we have placed brightness_control.png image in common directory.
index.css has style defined for the page.
CSS:
.container {
flex-direction: column;
justify-content: center;
align-items: center;
left: 0px;
top: 0px;
background-color: #192841;
width: 454px;
height: 454px;
}
.image {
width: 64px;
height: 64px;
justify-content: center;
margin-bottom: 15px;
margin-left: 10px;
margin-top: 20px;
}
.showList {
flex-direction: column;
width: 300px;
margin-bottom: 10px;
margin-top: 10px;
height: 250px;
}
.showListItem {
flex-direction: column;
align-items: center;
width: 300px;
background-color: #192841;
height: 80px;
}
.title {
font-size: 30px;
}
.content {
margin-bottom: 10px;
margin-top: 10px;
}
.divider {
width: 454px;
height: 2px;
margin-bottom: 10px;
margin-top: 10px;
background-color: lightgrey;
}
Firstly, we need to import the brightness module.
Code:
import brightness from '@system.brightness';
Once user selects predefined brightness value from list, we will call brightness.setValue(value). The value is an integer ranging from 1 to 255.
JavaScript:
setBrightness() {
let _brigtenessValue = this.brigtenessValue;
brightness.setValue({
value: _brigtenessValue,
success: function(){
console.log('handling set brightness success.');
},
fail: function(data, code){
console.log('handling set brightness value fail, code:' + code + ', data: ' + data);
},
});
}
To set screen brightness adjustment mode, we will call brightness.setValue().The value can be 0 or 1.
0: The screen brightness is manually adjusted.
1: The screen brightness is automatically adjusted.
JavaScript:
setBrightnessMode(modeValue) {
brightness.setMode({
mode: modeValue,
success: function(){
console.log('handling set mode success.');
},
fail: function(data, code){
console.log('handling set mode fail, code:' + code + ', data: ' + data);
},
});
}
Code snippet for app.js
JavaScript:
import brightness from '@system.brightness';
export default {
data: {
listData: ['Auto Mode' , '10%', '30%', '50%', '75%', '100%'],
brigtenessValue : 1,
AUTO_MODE : 1,
MANUAL_MODE : 0,
},
onItemClick(value) {
console.log(value);
if(value === 'Auto Mode') {
this.setBrightnessMode(this.AUTO_MODE);
}
else {
this.setBrightnessMode(this.MANUAL_MODE);
let valueInt = parseInt(value.substring(0, value.length -1));
this.brigtenessValue = 255 * (value/100);
this.setBrightness();
}
},
setBrightnessMode(modeValue) {
brightness.setMode({
mode: modeValue,
success: function(){
console.log('handling set mode success.');
},
fail: function(data, code){
console.log('handling set mode fail, code:' + code + ', data: ' + data);
},
});
},
setBrightness() {
let _brigtenessValue = this.brigtenessValue;
brightness.setValue({
value: _brigtenessValue,
success: function(){
console.log('handling set brightness success.');
},
fail: function(data, code){
console.log('handling set brightness value fail, code:' + code + ', data: ' + data);
},
});
},
}
Tips and Tricks
If you are using simulator for development, you can check the changed brightness value by clicking hamburger menu.
Conclusion
In this article, we have learnt how to create simple app to control Brightness of wearable device. You only need one touch to change current display brightness to one of the predefined values or select the "Auto Brightness" mode.
References
Harmony Official document:
Document
developer.harmonyos.com
Harmony OS JS API
Read In Forum
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Article Introduction
In this article we will develop Qibla finder application for Huawei Smart Watch device using Huawei DevEco Studio (HarmonyOS). We will fetch Location and Compass API’s of HarmonyOS JS language to develop Application.
1. Create New Project
Let’s create Smart Watch Project and choosing ability template, Wearable and Empty Feature Ability (JS)
Define project name, package name and relevant directory where you want to save your project.
2. Preparing Files and Permission
Let’s first add images and permissions which we will use for project.
All project images will be under common/images folder, check below screenshot.
Next we need to add permissions for Internet and Location under config.json file.
JSON:
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.LOCATION",
"reason": "get Qibla direction",
"usedScene": {
"ability": [
"default"
],
"when": "always"
}
}
]
3. Compass Development
In Compass screen development we will cover Location permission, Location fetching, location error and compass degree value.
Let’s start development without wasting more time.
Styling:
index.css:
CSS:
.stack {
width: 454px;
height: 454px;
justify-content: center;
background-color: whitesmoke;
}
.container {
background-color: whitesmoke;
}
.compass-container {
display: flex;
justify-content: center;
align-items: center;
left: 0px;
top: 0px;
width: 454px;
height: 454px;
background-color: whitesmoke;
}
.container-location-loading{
background-image: url('/common/images/background.png');
flex-direction: column;
padding-top: 0px;
padding-bottom: 0px;
height: 456px;
width: 456px;
}
.error-container {
background-image: url('/common/images/background.png');
padding-top: 0px;
padding-bottom: 0px;
height: 456px;
width: 100%;
}
.location_loading{
object-fit:contain;
height: 456px;
width: 292px;
}
.column{
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
}
.needle{
left: 0px;
top: 0px;
width: 220px;
height: 220px;
background-color: transparent;
z-index:99;
}
.compass, .compass2{
left: 0px;
top: 0px;
width: 220px;
height: 220px;
background-color: transparent;
z-index:98;
}
.qibla_style{
display: flex;
left: 0px;
top: 0px;
width: 220px;
height: 220px;
background-color: transparent;
z-index:100000;
}
.error_title{
display: flex;
color: red;
width: 100%;
height: 100%;
justify-content: center;
align-content: center;
text-align: center;
font-size: 24px;
}
.button-container{
display: flex;
flex-direction: row;
justify-content: center;
align-content: space-around;
position: absolute;
bottom: 10px;
}
Layout:
Location Loading Animation:
Code:
<stack if="{{isLocationLoading === true && isLocationError === false}}" class="container-location-loading">
<image src="../../common/images/location_animation.gif" class="location_loading" />
</stack>
Location Loading Output:
Location Error and Retry:
Code:
<stack if="{{isLocationLoading === false && isLocationError === true}}" class="error-container">
<text class="error_title">Location not fetch. Try again</text>
<div class="button-container">
<button type="circle" icon="/common/images/exit.png" onclick="exit"></button>
<button type="circle" icon="/common/images/refresh.png" onclick="retry"></button>
</div>
</stack>
Location Error Output:
Compass UI:
Code:
<stack class="compass-container" if="{{isLocationLoading === false && isLocationError === false}}">
<stack class="compass" style="transform:{{compass_transform}}">
<div class="needle" style="transform:{{needle_transform}}">
<image src="/common/images/needle.png"></image>
</div>
<div class="compass" >
<image src="/common/images/compass.png"></image>
</div>
</stack>
<div class="qibla_style">
<image src="/common/images/qibla.png"></image>
</div>
</stack>
Compass UI Output:
JS code:
Structural - Code:
Code:
import sensor from '@system.sensor';
import brightness from '@system.brightness';
import geolocation from '@system.geolocation';
import app from '@system.app';
export default {}
Data:
Code:
data: {
compass_transform: "rotate(0deg)",
needle_transform: "rotate(0deg)",
isLocationLoading: true,
isLocationError: false,
}
Common - Code:
Code:
onReady() {
this.setBrightnessKeepScreenOn();
},
onInit() {
this.initLocationCompass();
},
exit(){
app.terminate();
},
retry(){
this.isLocationLoading = true;
this.isLocationError = false;
this.initLocationCompass();
},
onDestroy() {
sensor.unsubscribeCompass();
},
// Setting the screen to be steady on
setBrightnessKeepScreenOn: function () {
brightness.setKeepScreenOn({
keepScreenOn: true,
success: function () {
console.log("handling set keep screen on success")
},
fail: function (data, code) {
console.log("handling set keep screen on fail, code:" + code);
}
});
},
onBackPress() {
sensor.unsubscribeCompass();
}
Location Fetching - Code:
Code:
initLocationCompass(){
var _this = this;
this.locationLoading().then(result => {
console.info("Location: " + result);
_this.loadCompass(result);
_this.isLocationLoading = false;
_this.isLocationError = false;
}, error => {
console.info("Location: error ->" + error);
_this.isLocationLoading = false;
_this.isLocationError = true;
});
},
locationLoading() {
return new Promise(function (resolve, reject) {
return geolocation.getLocation({
success: function (data) {
console.log('success get location data. latitude:' + data.latitude + 'long:' + data.longitude);
return resolve({
latitude: data.latitude,
longitude: data.longitude
});
},
fail: function (data, code) {
console.log('fail to get location. code:' + code + ', data:' + data);
return reject({
error: 'fail to get location. code:' + code + ', data:' + data
});
},
});
});
},
Compass - Code:
Code:
loadCompass(coordinates = {
latitude: 24.7136,
longitude: 46.6753
}) {
var _this = this;
var qiblaDirection = parseFloat(this.qibla(coordinates));
console.log("compass: qiblaDirection: " + qiblaDirection);
_this.needle_transform = "rotate(" + qiblaDirection + "deg)";
sensor.subscribeCompass({
success: function (ret) {
var direction = ret.direction;
var compassDirection = (360 - direction);
_this.compass_transform = "rotate(" + compassDirection + "deg)";
console.log("compass: compassDirection: " + direction);
},
fail: function (data, code) {
console.error('compass: subscribe compass fail, code: ' + code + ', data: ' + data);
},
});
},
Qibla Direction - Code:
Code:
qibla(coordinates) {
const makkah = {
latitude: 21.42252,
longitude: 39.82621
};
const term1 = Math.sin(this.degreesToRadians(makkah.longitude) - this.degreesToRadians(coordinates.longitude));
const term2 = Math.cos(this.degreesToRadians(coordinates.latitude)) * Math.tan(this.degreesToRadians(makkah.latitude));
const term3 = Math.sin(this.degreesToRadians(coordinates.latitude)) * Math.cos(this.degreesToRadians(makkah.longitude) - this.degreesToRadians(coordinates.longitude));
const angle = Math.atan2(term1, term2 - term3);
return this.unwindAngle(this.radiansToDegrees(angle));
},
degreesToRadians(degrees) {
return degrees * Math.PI / 180.0;
},
radiansToDegrees(radians) {
return radians * 180.0 / Math.PI;
},
normalizeToScale(number, max) {
return number - max * Math.floor(number / max);
},
unwindAngle(angle) {
return this.normalizeToScale(angle, 360.0);
},
Compass Screen Notes:
To manage Layout, we need to use <stack> to overlap UI component in layers. First we need to fetch location data and identify the Qibla direction in degree. And call Compass JS API to get compass degree and manage the UI accordingly.
4. Result
Tips and Tricks:
Requesting some data from internet, you must need to add Internet permission in config.json file.
Fetching Location data, you must need to add Internet Permission in config.json file.
Use Dev Eco Studio Previewer to check the screen layout and design. Previewer is developer friendly to Hot release changes on fly.
For better management of big application it’s a good practice to centralize you common scripts and common style in common folder. Add images folder for complete application images.
In JS script when you make some variable, in callback functions you can store the reference of this to some variable and then call reference variable. Like var _this = this.
References:
HarmonyOS JS API Official Documentation: click here
Geographic Location Documentation: click here
Sensor Documentation: click here
Conclusion:
Developers can able to fetch user location data and compass data to make Qibla finder application. While developing application for HarmonyOS developer can get benefit for both JS and JAVA language.
Original Source