OpenHarmony实战开发-如何使用ArkTS来实现折叠展开动效。

652 篇文章 4 订阅
647 篇文章 6 订阅

场景介绍

由于目前移动端需要展示的内容越来越多,但是移动端的空间弥足珍贵,在有限的空间内不可能罗列展示全部种类内容,因此折叠/展开功能就可以解决当前问题,本文就介绍下如何使用ArkTS来实现折叠展开动效。

效果呈现

折叠展开动效定义:点击展开按钮,下拉动画展示内容,点击折叠按钮,折叠动画折叠内容。 本例最终效果如下:

在这里插入图片描述

运行环境

本例基于以下环境开发,开发者也可以基于其它适配的版本进行开发:

  • IDE: DevEco Studio 3.1 Release
  • SDK: Ohos_sdk_public 3.2.12.5(APIVersion 9 Release)

实现思路

创建折叠时的文本组件,根据List组件中的groupcollapse和groupexpand事件自定义一个CollapseAndExpand组件,父组件通过维护flag和onFlagChange来控制折叠/展开的动效,设置动效所需的参数,添加逻辑来展示展开后的文本。

开发步骤

1.创建自定义接口IRowItem。 具体代码如下:

interface IRowItem {
    id?: number;
    title?: string;
    name1?: string;
    name2?: string;
    name3?: string;
    flag?: boolean;
    type?: string;
    onFlagChange?: () => void;
}

2.创建自定义组件CollapseAndExpandDemo,根据自定义接口IRowItem添加内容,创建UI展示文本。 具体代码如下:

@Entry
@Component{
    ...
    build() {
        Column() {
            Row() {
                Image($r("app.media.ic_public_back"))
                .width(20)
                .height(20)
                Text('周免英雄')
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .margin({ left: 10 })
            }
            .width('100%')
            .margin({ bottom: 30 })
    
            Column() {
                RowItem({ props: { title: 'AAAAA', name1: 'BBBBB', name2: 'CCCCC', name3: '武器大师' } })
                // 文本折叠时,type为DOWN
                RowItem({ props: { name1: 'DDDDD', name2: 'EEEEE', name3: 'FFFFF', type: 'DOWN', onFlagChange: this.onFlagChange } })  

                //被折叠的文本内容
                ...  

                RowItem({ props: { title: '商城', name1: '免费', name2: '特价', name3: 'VIP' } })
                RowItem({ props: { title: '分类', name1: '按职业', name2: '按位置', name3: '按城市' } })
            }
            .width('100%')
}

被折叠文本信息。 具体代码如下:

CollapseAndExpand({
    items: [
        { id: 0, name1: 'GGGGG', name2: 'HHHHH', name3: 'JJJJJ' },
        { id: 1, name1: 'KKKKK', name2: 'LLLLL', name3: 'MMMMM' },
        { id: 2, name1: 'NNNNN', name2: 'OOOOO', name3: 'PPPPP' },
        // 文本展开时,type为UP
        { id: 3, name1: 'QQQQQ', name2: 'RRRRR', name3: 'SSSSS', type: 'UP', onFlagChange: this.onFlagChange }
    ],
})

3.将步骤2创建的文本进行渲染。 具体如下:

build() {
    Flex() {
      Text(this.props.title)
        .fontSize(14)
        .fontWeight(FontWeight.Bold)
        .layoutWeight(1)
        .fontColor(Color.Red)
        .margin({ right: 10 })
      Flex({ alignItems: ItemAlign.Center }) {
        Text(this.props.name1).fontSize(14).margin({ right: 10 })
        Text(this.props.name2).fontSize(14).margin({ right: 10 })
        Text(this.props.name3).fontSize(14).margin({ right: 10 })
        ...
      }
    }
  }

4.创建自定义组件CollapseAndExpand。 根据自定义组件说明动效,@Provide负责数据更新,并且触发渲染;@Consume在感知数据更新后,重新渲染。 具体代码如下:

@Entry
@Component
struct CollapseAndExpandDemo {
  @Provide("flag") flag: boolean = false
  private onFlagChange = () => {
    animateTo({   
        duration: 650,
        curve: Curve.Smooth
    }, () => {
        this.flag = !this.flag;
    })
  } 

  ...

@Component
struct CollapseAndExpand {
    private items: IRowItem[] = [];
    @Consume("flag") flag: boolean;
    
    build() {
        Column() {
            ForEach(this.items, (item: IRowItem) => {
                RowItem({ props: item })
            }, (item: IRowItem) => item.id.toString())
        }
        .width('100%')
        .clip(true)
        .height(this.flag ? 130 : 0)
    }
}

5.根据步骤4最终的flag以及props的type值,判断折叠展开的效果实现。 具体代码如下:

build() {
    ...
    // 当文本折叠(flag为false且type为down)时,展示展开按钮
    // 当文本展开(flag为true且type为up)时,展示折叠按钮
    if (!this.flag && this.props.type === 'DOWN' || this.flag && this.props.type === 'UP') {
    Image($r("app.media.icon"))
        .width(16)
        .height(16)
        .objectFit(ImageFit.Contain)
        .rotate({ angle: !this.flag && this.props.type === 'DOWN' ? 0 : 180 })
        // 点击按钮后旋转180°,展示折叠按钮
        .onClick(() =>
        this.props.onFlagChange()
        )
        .transition({ type: TransitionType.All, opacity: 0 })
    }
}   

完整代码

示例代码如下:

interface IRowItem {
    id?: number;
    title?: string;
    name1?: string;
    name2?: string;
    name3?: string;
    flag?: boolean;
    type?: string;
    onFlagChange?: () => void;
}

@Entry
@Component
struct CollapseAndExpandDemo {
    @Provide("flag") flag: boolean = false
    private onFlagChange = () => {
        animateTo({  
            duration: 650,
            curve: Curve.Smooth
            }, () => {
                this.flag = !this.flag;
                })
    }

    build() {
        Column() {
            Row() {
                Image($r("app.media.ic_public_back")).width(20).height(20)
                Text('周免英雄')
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .margin({ left: 10 })
            }
            .width('100%')
            .margin({ bottom: 30 })

            Column() {
                RowItem({ 
                    props: { title: '英雄', name1: 'AAAAA', name2: 'BBBBB', name3: 'CCCCC' } })
                RowItem({ 
                    props: { 
                        name1: 'DDDDD', 
                        name2: 'EEEEE', 
                        name3: 'FFFFF', 
                        // 文本折叠时,type为DOWN
                        type: 'DOWN', 
                        onFlagChange: this.onFlagChange  
                    }
                })
                // 直接调用折叠展开组件
                CollapseAndExpand({
                    items: [
                        { id: 0, name1: 'GGGGG', name2: 'HHHHH', name3: 'JJJJJ' },
                        { id: 1, name1: 'KKKKK', name2: 'LLLLL', name3: 'MMMMM' },
                        { id: 2, name1: 'NNNNN', name2: 'OOOOO', name3: 'PPPPP' },
                        { id: 3, 
                        name1: 'QQQQQ', 
                        name2: 'RRRRR', 
                        name3: 'SSSSS', 
                        // 文本折叠时,type为UP
                        type: 'UP', 
                        onFlagChange: this.onFlagChange }  
                    ],
                })

                RowItem({ props: { title: '商城', name1: '免费', name2: '特价', name3: 'VIP' } })
                RowItem({ props: { title: '分类', name1: '按职业', name2: '按位置', name3: '按城市' } })
            }
            .width('100%')

        }
        .height('100%')
        .padding({ top: 30, right: 30, left: 30 })
  }
}

@Component
struct RowItem {
    private props: IRowItem;
    @Consume("flag") flag: boolean

    build() {
        Flex() {
            Text(this.props.title)
            .fontSize(14)
            .fontWeight(FontWeight.Bold)
            .layoutWeight(1)
            .fontColor(Color.Red)
            .margin({ right: 10 })
            Flex({ alignItems: ItemAlign.Center }) {
                Text(this.props.name1).fontSize(14).margin({ right: 10 })
                Text(this.props.name2).fontSize(14).margin({ right: 10 })
                Text(this.props.name3).fontSize(14).margin({ right: 10 })

                // 当文本折叠(flag为false且type为down)时,展示展开按钮
                // 当文本展开(flag为true且type为up)时,展示折叠按钮
                if (!this.flag && this.props.type === 'DOWN' || this.flag && this.props.type === 'UP') {
                    Image($r("app.media.ic_public_arrow_down_0"))
                    .width(16)
                    .height(16)
                    .objectFit(ImageFit.Contain)
                    .rotate({ angle: !this.flag && this.props.type === 'DOWN' ? 0 : 180 }) 
                    // 点击展开按钮后旋转180°,展示折叠按钮
                    .onClick(() => this.props.onFlagChange())
                    .transition({ type: TransitionType.All, opacity: 0 })
                }
            }
            .layoutWeight(3)
        }
        .width('100%')
        .height(16)
        .margin({ top: 15 })
    }
}

@Component
struct CollapseAndExpand {
    private items: IRowItem[] = [];
    @Consume("flag") flag: boolean;

    build() {
        Column() {
            ForEach(this.items, (item: IRowItem) => {
                RowItem({ props: item })
            }, (item: IRowItem) => item.id.toString())
        }
        .width('100%')
        .clip(true)
        .height(this.flag ? 130 : 0)
    }
}

我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI、实战开发视频教程》以及《鸿蒙生态应用开发白皮书V2.0PDF》《鸿蒙开发学习手册》(共计890页)鸿蒙开发资料等…希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG

在这里插入图片描述

应用开发中级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

应用开发中高级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

南北双向高工技能基础:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

全网首发-工业级 南向设备开发就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
折叠面板是一个常见的 UI 组件,可以在 Web 页面上实现内容的展开与收缩。以下是一个 HTML 右边折叠面板的实现示例: HTML 代码: ```html <div class="panel-container"> <div class="panel-header"> <h3>折叠面板标题</h3> <span class="panel-arrow"></span> </div> <div class="panel-content"> <p>折叠面板内容</p> </div> </div> ``` CSS 代码: ```css .panel-container { position: relative; width: 400px; height: 100%; } .panel-header { position: relative; z-index: 1; height: 40px; background-color: #f0f0f0; border-bottom: 1px solid #d9d9d9; cursor: pointer; } .panel-header h3 { margin: 0; padding: 0 20px; line-height: 40px; font-size: 16px; font-weight: bold; color: #333; } .panel-arrow { position: absolute; top: 50%; right: 20px; width: 0; height: 0; margin-top: -5px; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid #999; transition: transform 0.3s ease; } .panel-content { position: absolute; top: 40px; right: 0; z-index: 0; width: 0; height: 0; overflow: hidden; background-color: #fff; transition: width 0.3s ease; } .panel-container.active .panel-header .panel-arrow { transform: rotate(180deg); } .panel-container.active .panel-content { width: 300px; height: 300px; } ``` 解释: 1. `.panel-container` 设置容器的宽度和高度,并设置为相对定位,以便内部元素进行定位。 2. `.panel-header` 设置折叠面板的标题栏样式,包括高度、背景色、边框和光标样式。 3. `.panel-header h3` 设置标题栏标题的样式,包括字体大小、颜色和粗细等。 4. `.panel-arrow` 设置标题栏右侧的箭头样式,包括定位、大小和颜色等。使用 `transition` 属性实现箭头旋转效果。 5. `.panel-content` 设置折叠面板的内容区样式,包括定位、大小、背景色和过渡效果等。使用 `overflow: hidden` 属性隐藏内容超出部分。 6. `.panel-container.active .panel-header .panel-arrow` 和 `.panel-container.active .panel-content` 通过 `.active` 类实现面板的展开和收缩效果。 以上是一个简单的 HTML 右边折叠面板的实现示例。可以根据实际需求调整样式和布局。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值