添加交互可以通过在组件上关联事件实现。本节将介绍如何用div、text、image组件关联click事件,构建一个如下图所示的点赞按钮。
点赞按钮通过一个div组件关联click事件实现。div组件包含一个image组件和一个text组件:
click事件作为一个函数定义在js文件中,可以更改isPressed的状态,从而更新显示的image组件。如果isPressed为真,则点赞数加1。该函数在hml文件中对应的div组件上生效,点赞按钮各子组件的样式设置在css文件当中。具体的实现示例如下:
<!-- test.hml -->
<!-- 点赞按钮 -->
<div>
<div class="like" onclick="likeClick">
<image class="like-img" src="{
{likeImage}}" focusable="true"></image>
<text class="like-num" focusable="true">{
{total}}</text>
</div>
</div>
/* test.css */
.like {
width: 104px;
height: 54px;
border: 2px solid #bcbcbc;
justify-content: space-between;
align-items: center;
margin-left: 72px;
border-radius: 8px;
}
.like-img {
width: 33px;
height: 33px;
margin-left: 14px;
}
.like-num {
color: #bcbcbc;
font-size: 20px;
margin-right: 17px;
}
// test.js
export default {
data: {
likeImage: '/common/unLike.png',
isPressed: false,
total: 20,
},
likeClick() {
var temp;
if (!this.isPressed) {
temp = this.total + 1;
this.likeImage = '/common/like.png';
} else {
temp = this.total - 1;
this.likeImage = '/common/unLike.png';
}
this.total = temp;
this.isPressed = !this.isPressed;
},
}
除此之外,还提供了很多表单组件,例如开关、标签、滑动选择器等。
动画分为静态动画和连续动画。
静态动画的核心是transform样式,主要可以实现以下三种变换类型,一次样式设置只能实现一种类型变换。
<!-- test.hml -->
<div class="container">
<text class="translate">hello</text>
<text class="rotate">hello</text>
<text class="scale">hello</text>
</div>
/* test.css */
.container {
flex-direction: column;
align-items: center;
}
.translate {
height: 150px;
width: 300px;
font-size: 50px;
background-color: #008000;
transform: translate(200px);
}
.rotate {
height: 150px;
width: 300px;
font-size: 50px;
background-color: #008000;
transform-origin: 200px 100px;
transform: rotateX(45deg);
}
.scale {
height: 150px;
width: 300px;
font-size: 50px;
background-color: #008000;
transform: scaleX(1.5);
}
静态动画只有开始状态和结束状态,没有中间状态,如果需要设置中间的过渡状态和转换效果,需要使用连续动画实现。
连续动画的核心是animation样式,它定义了动画的开始状态、结束状态以及时间和速度的变化曲线。通过animation样式可以实现的效果有:
animation样式需要在css文件中先定义keyframe,在keyframe中设置动画的过渡效果,并通过一个样式类型在hml文件中调用。animation-name的使用示例如下:
<!-- test.hml -->
<div class="item-container">
<text class="header">animation-name</text>
<div class="item {
{colorParam}}">
<text class="txt">color</text>
</div>
<div class="item {
{opacityParam}}">
<text class="txt">opacity</text>
</div>
<input class="button" type="button" name="" value="show" onclick="showAnimation"/>
</div>
/* test.css */
.item-container {
margin-right: 60px;
margin-left: 60px;
flex-direction: column;
}
.header {
margin-bottom: 20px;
}
.item {
background-color: #f76160;
}
.txt {
text-align: center;
width: 200px;
height: 100px;
}
.button {
width: 200px;
font-size: 30px;
background-color: #09ba07;
}
.color {
animation-name: Color;
animation-duration: 8000ms;
}
.opacity {
animation-name: Opacity;
animation-duration: 8000ms;
}
@keyframes Color {
from {
background-color: #f76160;
}
to {
background-color: #09ba07;
}
}
@keyframes Opacity {
from {
opacity: 0.9;
}
to {
opacity: 0.1;
}
}
// test.js
export default {
data: {
colorParam: '',
opacityParam: '',
},
showAnimation: function () {
this.colorParam = '';
this.opacityParam = '';
this.colorParam = 'color';
this.opacityParam = 'opacity';
},
}
手势表示由单个或多个事件识别的语义动作(例如:点击、拖动和长按)。一个完整的手势也可能由多个事件组成,对应手势的生命周期。支持的事件有:
触摸
点击
click:用户快速轻敲屏幕。
长按
longpress:用户在相同位置长时间保持与屏幕接触。
具体的使用示例如下:
<!-- test.hml -->
<div class="container">
<div class="text-container" onclick="click">
<text class="text-style">{
{onClick}}</text>
</div>
<div class="text-container" ontouchstart="touchStart">
<text class="text-style">{
{touchstart}}</text>
</div>
<div class="text-container" ontouchmove="touchMove">
<text class="text-style">{
{touchmove}}</text>
</div>
<div class="text-container" ontouchend="touchEnd">
<text class="text-style">{
{touchend}}</text>
</div>
<div class="text-container" ontouchcancel="touchCancel">
<text class="text-style">{
{touchcancel}}</text>
</div>
<div class="text-container" onlongpress="longPress">
<text class="text-style">{
{onLongPress}}</text>
</div>
</div>
/* test.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.text-container {
margin-top: 10px;
flex-direction: column;
width: 750px;
height: 50px;
background-color: #09ba07;
}
.text-style {
width: 100%;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #ffffff;
}
// test.js
export default {
data: {
touchstart: 'touchstart',
touchmove: 'touchmove',
touchend: 'touchend',
touchcancel: 'touchcancel',
onClick: 'onclick',
onLongPress: 'onlongpress',
},
touchCancel: function (event) {
this.touchcancel = 'canceled';
},
touchEnd: function(event) {
this.touchend = 'ended';
},
touchMove: function(event) {
this.touchmove = 'moved';
},
touchStart: function(event) {
this.touchstart = 'touched';
},
longPress: function() {
this.onLongPress = 'longpressed';
},
click: function() {
this.onClick = 'clicked';
},
}
很多应用由多个页面组成,比如用户可以从音乐列表页面点击歌曲,跳转到该歌曲的播放界面。需要通过页面路由将这些页面串联起来,按需实现跳转。
页面路由router根据页面的url找到目标页面,从而实现跳转。以最基础的两个页面之间的跳转为例,具体实现步骤如下:
index和detail这两个页面均包含一个text组件和button组件:text组件用来指明当前页面,button组件用来实现两个页面之间的相互跳转。hml文件代码示例如下:
<!-- index.hml -->
<div class="container">
<text class="title">This is the index page.</text>
<button type="capsule" value="Go to the second page" class="button" onclick="launch"></button>
</div>
<!-- detail.hml -->
<div class="container">
<text class="title">This is the detail page.</text>
<button type="capsule" value="Go back" class="button" onclick="launch"></button>
</div>
构建index和detail页面的页面样式,text组件和button组件居中显示,两个组件之间间距为50px。css代码如下(两个页面样式代码一致):
/* index.css */
/* detail.css */
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.title {
font-size: 50px;
margin-bottom: 50px;
}
为了使button组件的launch方法生效,需要在页面的js文件中实现跳转逻辑。调用router.push()接口将url指定的页面添加到路由栈中,即跳转到url指定的页面。在调用router方法之前,需要导入router模块。代码示例如下:
// index.js
import router from '@ohos.router';
export default {
launch() {
router.push ({
url: 'pages/detail/detail',
});
},
}
// detail.js
import router from '@ohos.router';
export default {
launch() {
router.back();
},
}
运行效果如下图所示: