积分481 / 贡献0

提问1答案被采纳34文章4

作者动态

    [经验分享] 属性动画示例 精华

    hyacinth养花人 显示全部楼层 发表于 2023-9-15 18:34:55
    场景介绍
    在日常开发过程中,通常会出现因为状态变化导致组件属性值发生变化,如:
    • 数字键盘按键时,对应数字按钮背景色加深,呈现被点击效果;放开按键时,呈现取消选中效果,
    • UI中图标按下时,图标出现弹性缩放效果,
    • 在做数据统计时,随着数据值的变化,统计曲线随之变化等动画效果, 本例将为大家介绍下如何通过属性动画实现上述场景。

    效果呈现
    效果图如下:
    场景1:属性动画
    attribute_animation.gif

    场景2:弹性动态
    Elastic_animation.gif

    场景3:曲线动画
    time_curve.gif

    运行环境
    本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发
    • IDE: DevEco Studio 3.1 Release
    • SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release)

    场景1:属性动画
    实现思路
    本实例涉及到的主要特性及其实现方案如下:
    • 通过Column、Grid、button、Text等关键组件以及visibility属性搭建UI局框架,以及渲染数字按钮。
    • 设置状态变量flag,用来控制属性状态的变化,同时向Button组件添加onTouch事件,更新按钮的当前状态,从而可以根据监听到的按钮状态加载对应的动画效果   。

    • 默认状态为按钮放开状态(flag为false)。
    • 当按钮按下时,更新按钮的状态(flag:false -> true)。
    • 当按钮放开时,更新按钮的状态(flag:true -> false)。

    • 根据按钮组件的按下/放开状态,通过三元运算判断,使用属性动画更新按钮的选中/取消效果。

    • 当按钮按下时,加载属性动画:按钮被选中效果。
    • 当按钮放开时,加载属性动画:按钮取消选中效果。

    开发步骤
    针对实现思路中所提到的内容,具体关键开发步骤如下:
    1. 通过Column、Grid、button、Text等关键组件以及visibility属性搭建UI框架,以及渲染数字按钮。
    具体代码如下:


    1.   private numGrid: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0, -1]

    2.   build() {
    3.     Row() {
    4.       Column() {
    5.         Grid() {
    6.           //通过ForEach循环遍历,显示数字数字按钮
    7.           ForEach(this.numGrid, (item, index) => {
    8.             GridItem() {
    9.               Button() {
    10.                 Text(`${item}`)
    11.                   .fontSize(30)
    12.               }
    13.               .backgroundColor('#fff')
    14.               .width(100)
    15.               .height(100)
    16.               // item为-1时,数字按钮不显示
    17.               .visibility(item == -1 ? Visibility.Hidden : Visibility.Visible)
    18.             }
    19.           }, item => item)
    20.         }
    21.         .columnsTemplate('1fr 1fr 1fr')
    22.         .rowsTemplate('1fr 1fr 1fr 1fr')
    23.         .columnsGap(10)
    24.         .rowsGap(10)
    25.         .width(330)
    26.         .height(440)
    27.       }
    28.       .width('100%')
    29.       .height('100%')
    30.     }
    31.   }
    复制代码
    2. 设置状态变量flag,用来控制属性状态的变化,同时向Button组件添加onTouch事件,更新按钮的当前状态,从而可以根据监听到的按钮状态加载对应的动画效果。
    具体代码如下:

    1. //状态变量flag,用于监听按钮按下和放开的状态,默认至为false(放开状态)
    2. @State flag: boolean = false;
    3. ...
    4. .onTouch((event:TouchEvent) => {
    5.     //当按钮按下时,更新按钮的状态(flag:false -> true)
    6.     if (event.type == TouchType.Down) {
    7.         this.flag = true
    8.         this.currIndex = index
    9.     }
    10.     //当按钮放开时,更新按钮的状态(flag:true -> false)
    11.     if (event.type == TouchType.Up) {
    12.         this.flag = false
    13.     }
    14. })
    复制代码
    3. 根据按钮组件的按下/放开状态,通过三元运算判断并更新按钮背景色。
    具体代码如下:
    1. Button(){
    2.     ...
    3.     // 当按钮被按下(flag变更为true)时,当前按钮backgroundColor属性变更("#fff" -> "#D2C3D5" )
    4.     // 当按钮被放开(flag变更为false)时,当前按钮backgroundColor属性变更("#D2C3D5" -> "#FFF" )
    5.     .backgroundColor(this.flag && this.currIndex == index ? '#D2C3D5' : '#fff')
    6.     .animation({
    7.         duration: 200
    8.     })
    9. }
    复制代码
    完整代码
    1. @Entry
    2. @Component
    3. struct Index {
    4.   private currIndex: number = -1
    5.   private numGrid: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0, -1]
    6.   //状态变量flag,用于监听按钮按下和放开的状态,默认至为false(放开状态)
    7.   @State flag: boolean = false;

    8.   build() {
    9.     Row() {
    10.       Column() {
    11.         Grid() {
    12.           ForEach(this.numGrid, (item, index) => {
    13.             GridItem() {
    14.               Button() {
    15.                 Text(`${item}`)
    16.                   .fontSize(30)
    17.               }
    18.                // 当按钮被按下(flag变更为true)时,当前按钮backgroundColor属性变更("#fff" -> "#D2C3D5" )
    19.                            // 当按钮被放开(flag变更为false)时,当前按钮backgroundColor属性变更("#D2C3D5" -> "#FFF" )
    20.               .backgroundColor(this.flag && this.currIndex == index ? '#D2C3D5' : '#fff')
    21.               .animation({
    22.                 duration: 200
    23.               })
    24.               .width(100)
    25.               .height(100)
    26.               .visibility(item == -1 ? Visibility.Hidden : Visibility.Visible)
    27.               .onTouch((event:TouchEvent) => {
    28.                 //当按钮按下时,更新按钮的状态(flag:false -> true)
    29.                 if (event.type == TouchType.Down) {
    30.                   this.flag = true
    31.                   this.currIndex = index
    32.                 }
    33.                 //当按钮放开时,更新按钮的状态(flag:true -> false)
    34.                 if (event.type == TouchType.Up) {
    35.                   this.flag = false
    36.                 }
    37.               })
    38.             }
    39.           }, item => item)
    40.         }
    41.         .columnsTemplate('1fr 1fr 1fr')
    42.         .rowsTemplate('1fr 1fr 1fr 1fr')
    43.         .columnsGap(10)
    44.         .rowsGap(10)
    45.         .width(330)
    46.         .height(440)
    47.       }
    48.       .width('100%')
    49.       .height('100%')
    50.     }
    51.   }
    52. }
    复制代码



    ©著作权归作者所有,转载或内容合作请联系作者

    您尚未登录,无法参与评论,登录后可以:
    参与开源共建问题交流
    认同或收藏高质量问答
    获取积分成为开源共建先驱

    精彩评论1

    everday

    沙发 发表于 2024-7-31 16:24:52
    有用的分享

    Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

    返回顶部