11

#夏日挑战赛# HarmonyOS - 自定义组件之switch开关-开源基础软件社区-51CTO.COM

 2 years ago
source link: https://ost.51cto.com/posts/13897
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

#夏日挑战赛# HarmonyOS - 自定义组件之switch开关 原创 精华

作者:姚显春

本文正在参加星光计划3.0–夏日挑战赛

最近在开发FA项目时使用到switch开关组件,该switch组件是基于JS扩展的类Web开发范式组件中的基础组件 。在使用的过程中发现了一些问题,比如:

1、设置宽高等样式属性不会改变switch组件本身的宽高,而是会修改switch组件的内边距;

2、switch组件存在一定比例的缩放。

使用switch组件在页面布局时存在上述等问题,但可通过一些技术手段(transform属性的scale)或一些替代方案,达到预期效果。基于此,通过现在已掌握的FA相关知识实现一个简单的自定义switch开关组件。

#夏日挑战赛# HarmonyOS - 自定义组件之switch开关-开源基础软件社区

基于css关键帧动画animation和@keyframes,通过对switch的滑块设置css属性position: absolute,并添加相应的动画class,即可达到switch开关的过渡效果。给switch设置固定的宽度和高度,保证switch组件不被缩放,在switch组件的外层包裹div组件,来实现布局的合理性。

css动画样式官方指导API:

属性名称 数据类型 默认值 描述
transform string - 支持同时设置平移/旋转/缩放等属性。
animation6+ string 0s ease 0s 1 normal none running none 格式:duration | timing-function | delay | iteration-count | direction | fill-mode| play-state | name,每个字段不区分先后,但是 duration / delay 按照出现的先后顺序解析。
animation-name string - 指定@keyframes的名称。
animation-fill-mode string none 指定动画开始和结束的状态:1、none:在动画执行之前和执行之后都不会应用任何样式到目标上;2、forwards:在动画结束后,目标将保留动画结束时的状态(在最后一个关键帧中定义);3、backwards6+:动画将在animation-delay期间应用第一个关键帧中定义的值。当animation-direction为"normal"或"alternate"时应用from关键帧中的值,当animation-direction为"reverse"或"alternate-reverse"时应用to关键帧中的值。4、both6+:动画将遵循forwards和backwards的规则,从而在两个方向上扩展动画属性。
animation-duration <time> 0 定义一个动画周期。支持的单位为[s(秒) | ms(毫秒) ],默认单位为ms,格式为:1000ms或1s。(注意:animation-duration 样式必须设置,否则时长为 0,则不会播放动画。)
animation-delay <time> 0 定义动画播放的延迟时间。支持的单位为[s(秒) | ms(毫秒) ],默认单位为ms,格式为:1000ms或1s。
translateX <length> | <percent> - X轴方向平移动画属性。

switch组件 hml 部分:

<div class="define-switch">
    <!-- switch 滑块背景包裹节点 -->
    <div class="switch-wrapper {{ isChecked ? 'bg-blue' : 'bg-grey'}}" onclick="handleClick"></div>
    <!-- switch 滑块 -->
    <div class="switch-block {{ isChecked ? 'closed' : 'opened'}}"></div>
</div>

switch组件 css 部分:

.define-switch {
    position: relative;
    padding: 2px;
}
.switch-wrapper {
    position: relative;
    width: 36px;
    height: 20px;
    background-color: rgba(0,0,0,0.05);
    border-radius: 25px;
}
.switch-block {
    position: absolute;
    left: 2px;
    top: 2px;
    width: 16px;
    height: 16px;
    background-color: #FFFFFF;
    border-radius: 8px;
}
.opened {
    animation-name: open;
    animation-duration: 1s;
    animation-fill-mode: forwards;
}
.closed {
    animation-name: close;
    animation-duration: 1s;
    animation-fill-mode: forwards;
}
.bg-blue {
    background-color: #0A59F7;
}
.bg-grey {
    background-color: rgba(0,0,0,0.05);
}
@keyframes open {
    from {
        transform: translateX(16px);
    }
    to {
        transform: translateX(0px);
    }
}
@keyframes close {
    from {
        transform: translateX(0px);
    }
    to {
        transform: translateX(16px);
    }
}

switch组件 js 部分:

export default {
    name: 'DefineSwitch',
    data() {
        return {
            isChecked: false,
        }
    },
    handleClick(evt) {
        console.log('事件对象event:' + JSON.stringify(evt) + this.isChecked);
        this.isChecked = ! this.isChecked; // 修改isChecked的值
        this.$emit('switchChange', {checked: this.isChecked}); // 向父组件传递值
    }
}

父组件 hml中:

<!-- 引入组件 -->
<element name="mySwitch" src="../mySwitch/mySwitch.hml"></element>
<!-- 组件使用 -->
<div style="width: 40px; height: 24px;">
    <mySwitch @switch-change="handleSwitchChange"></mySwitch>
</div>

父组件 js中:

handleSwitchChange(e) {
    console.log('子组件传来的数据' + e.detail.checked); // 父组件中获取到switch的开关状态
}

实现中遇到的问题及解决方案:

问题描述:在实现关键帧动画时switch滑块执行完最后一帧动画后会回到原来的位置,导致动画执行效果不理想。

原因分析:动画属性animation的animation-fill-mode属性默认为none( 在动画执行之前和之后都不会应用任何样式到目标上 )。

解决方案:将animation-fill-mode属性设置为 forwards ( 在动画结束后,目标将保留动画结束时的状态 )。

此自定义组件是对css关键帧动画、父子组件通信的回顾,可能存在一些问题,望大家指正_。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-6-16 10:25:43修改

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK