赞
踩
介绍
本篇Codelab主要介绍组件动画animation属性设置。当组件的某些通用属性变化时,可以通过属性动画实现渐变效果,提升用户体验。
本Codelab使用的display接口处于mock阶段,在预览器上使用会显示白屏现象,可选择在真机或模拟器上运行。
源码下载
环境搭建
我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。
代码结构解读
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。
- ├──entry/src/main/ets // 代码区
- │ ├──common
- │ │ ├──constants
- │ │ │ ├──CommonConstants.ets // 公共常量类
- │ │ │ └──RefreshConstants.ets // 下拉刷新常量类
- │ │ └──utils
- │ │ ├──DimensionUtil.ets // 屏幕适配工具类
- │ │ └──GlobalContext.ets // 全局上下文工具类
- │ ├──entryability
- │ │ └──EntryAbility.ets // 程序入口类
- │ ├──pages
- │ │ ├──FileManagerIndex.ets // 文件管理Tab页
- │ │ └──TabIndex.ets // Tab管理页
- │ ├──view
- │ │ ├──RefreshAnimHeader.ets // 动画刷新组件
- │ │ ├──RefreshComponent.ets // 下拉刷新组件
- │ │ └──RefreshDefaultHeader.ets // 默认刷新组件
- │ └──viewmodel
- │ ├──AnimationModel.ets // 动画封装类
- │ └──CardModel.ets // 页签封装类
- └──entry/src/main/resources // 资源文件目录

自定义下拉组件
自定义下拉刷新通过自定义List组件RefreshComponent实现。在List容器中添加自定义刷新头部组件和其它的需要刷新部件,RefreshComponent提供了头部样式设置,刷新部件样式设置和刷新回调方法设置。
- // FileManagerIndex.ets
- RefreshComponent({
- headerStyle: RefreshHeaderStyle.CLOUD, // 头部样式设置
- itemLayout: (): void => this.ContentBody(), // 刷新部件样式
- displayHeight: (
- px2vp(this.deviceDisplay.height) - DimensionUtil.getVp($r('app.float.file_index_title_height'))),
- onRefresh: () => { // 刷新回调方法
- ...
- }
- })
- // RefreshComponent.ets
- if (this.headerStyle === RefreshHeaderStyle.DEFAULT) {
- RefreshDefaultHeader().height(RefreshConstants.REFRESH_HEADER_HEIGHT)
- } else if (this.headerStyle === RefreshHeaderStyle.CLOUD) {
- RefreshAnimHeader().height(RefreshConstants.REFRESH_HEADER_HEIGHT)
- }
- // FileManagerIndex.ets
- @Builder
- ContentBody() {
- Image($r('app.media.bg_content'))
- .width(CommonConstants.FULL_LENGTH)
- .height(DimensionUtil.getVp($r('app.float.content_height')))
- .objectFit(ImageFit.Fill)
- }
- // RefreshComponent.ets
- // 设置RefreshComponent刷新组件state状态的更新。
- @Consume(RefreshConstants.REFRESH_STATE_TAG) @Watch('onStateChanged') state: number;
-
- private onStateChanged() {
- switch (this.state) {
- case RefreshState.REFRESHING:
- if (this.onRefresh !== undefined) {
- this.onRefresh();
- }
- break;
- ...
- }
- }
-
- // 监听RefreshComponent中List组件的触摸事件。
- List({ scroller: this.listController }) {
- ListItem() {
- Column() {
- ...
- }
- ...
- }
- }
- ...
- .onTouch((event?: TouchEvent) => {
- if (!event) {
- return;
- }
- switch (event.type) {
- case TouchType.Down:
- if (this.state === RefreshState.IDLE) {
- this.state = RefreshState.DRAGGING;
- }
- break;
- case TouchType.Move:
- if (this.state === RefreshState.DRAGGING
- && this.listController.currentOffset().yOffset <= -RefreshConstants.REFRESH_EFFECTIVE_HEIGHT) {
- this.state = RefreshState.DRAGGING_REFRESHABLE;
- }
- break;
- case TouchType.Up:
- if (this.state === RefreshState.DRAGGING_REFRESHABLE) {
- this.headerOffset = 0;
- this.state = RefreshState.REFRESHING;
- }
- break;
- default:
- break;
- }
-
- // FileManagerIndex.ets
- //onRefresh事件没有做相关刷新,只做了模拟延时操作,开发者可以自行加入真实网络加载动作。
- onRefresh: () => {
- setTimeout(() => {
- this.state = RefreshState.COMPLETE;
- }, CommonConstants.REFRESH_DEFAULT_TIMEOUT);
- }

自定义刷新动画
本Codelab中自定义刷新是由5个图片的组合动画效果。
- // RefreshAnimHeader.ets
- @Builder AttrAnimIcons(iconItem: ClassifyModel) {
- Image(iconItem.imgRes)
- .width(px2vp(DimensionUtil.adaptDimension(this.iconWidth)))
- .position({ x: iconItem.posX })
- .objectFit(ImageFit.Contain)
- .animation({
- duration: CommonConstants.REFRESH_HEADER_ITEM_ANIM_DURATION,
- tempo: CommonConstants.REFRESH_HEADER_ITEM_ANIM_TEMPO,
- delay: iconItem.delay,
- curve: Curve.Linear,
- playMode: PlayMode.Alternate,
- iterations: CommonConstants.REFRESH_HEADER_ITEM_ANIM_ITERATIONS
- })
- }
- // RefreshAnimHeader.ets
- @Consume(RefreshConstants.REFRESH_STATE_TAG) @Watch('onStateCheck') state: number;
-
- private onStateCheck() {
- if (this.state === RefreshState.REFRESHING) {
- this.iconWidth = CommonConstants.REFRESH_HEADER_ITEM_SCALE_WIDTH;
- } else {
- this.iconWidth = CommonConstants.REFRESH_HEADER_ITEM_DEFAULT_WIDTH;
- }
- }
总结
您已经完成了本次Codelab的学习,并了解到以下知识点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。