【HarmonyOS】层级轮播卡片效果

【HarmonyOS】层级轮播卡片效果

一、功能效果:

在这里插入图片描述
1.上下堆叠由大到小的卡片层叠效果。

2.上层卡片可手势左右滑动,自动左滑动。

3.三层卡片随滑动,内容进行依次切换。

二、开发思路

【完整代码见章节三】

1.最上层使用swiper进行轮播效果的实现。

HeadSwiperLayerView() {Swiper(this.swiperController) {this.HeadCard()this.MiddenCard()this.EndCard()}.loop(true).autoPlay(true).indicator(false).duration(500).curve(Curve.Friction).displayMode(SwiperDisplayMode.STRETCH).onChange(this.monChangeCallBack).onAnimationEnd(this.monAnimationEndCallBack)}HeadCard() {Row() {if (this.HEAD_INDEX == this.mIndex) {Image(this.mImageResource[this.HEAD_INDEX]).BGCardCardWidthAndHeight().opacity(this.mCardOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Blue)}}.BGWidthAndHeight()}// MiddenCard EndCard 卡片依照HeadCard进行创建

2.下层两个卡片使用stack堆叠,依次显示。

build() {Stack({ alignContent: Alignment.Center }) {// 最底层卡片this.EndLayerView()// 中间层卡片this.MiddenLayerView()// 最上层swiper滑动层this.HeadSwiperLayerView()}}

3.整体卡片内容通过list数据进行链式切换。

  // 卡片图片资源池 mImageResource: Array<string | Resource > = [$r("app.media.icon_img1"),$r("app.media.icon_img2"),$r("app.media.icon_img3"),$r("app.media.icon_img4"),$r("app.media.icon_img5"),];

4.调整切换的index下标数据,控制数据切换,和逻辑计算。

  getImageResource(current: number, mIndex: number) {let currentPage: string | Resource = ''if (current == this.END_INDEX) {if (mIndex == this.HEAD_INDEX) {currentPage = this.mImageResource[2];} else if (mIndex == this.MIDDEN_INDEX) {currentPage = this.mImageResource[0];} else if (mIndex == this.END_INDEX) {currentPage = this.mImageResource[1];}} else if (current == this.MIDDEN_INDEX) {if (mIndex >= 2) {currentPage = this.mImageResource[0];} else {currentPage = this.mImageResource[mIndex+1];}} else if (current == this.HEAD_INDEX) {currentPage = this.mImageResource[this.mIndex];}return currentPage;}

5.细磨效果,添加透明度动画润色过渡操作的效果。(为了效果更好后续也可添加移动,放大缩小等。示例代码只是添加了透明度。)

三、DEMO示例代码:

滑动组件View
SlidingCardView.ets

/*** 层叠轮播图*/

export default struct SlidingCardView {// 滑动层 透明背景宽高private BG_WIDTH: number = px2vp(800);private BG_HEIGHT: number = px2vp(800);// 滑动层 可视卡片宽高private BG_CARD_WIDTH: number = px2vp(700);private BG_CARD_HEIGHT: number = px2vp(800);private CARD_ANIM_START: number = 0.1;private CARD_ANIM_END: number = 1;private LAYER_CARD_ANIM_START: number = 0.9;private LAYER_CARD_ANIM_END: number = 1;// 移动下标 mIndex: number = 0; mCardOpacity: number = this.CARD_ANIM_END; mLayerOpacity: number = this.LAYER_CARD_ANIM_END;// 卡片图片资源池 mImageResource: Array<string | Resource > = [$r("app.media.icon_img1"),$r("app.media.icon_img2"),$r("app.media.icon_img3"),$r("app.media.icon_img4"),$r("app.media.icon_img5"),];private swiperController: SwiperController = new SwiperController();private END_INDEX: number = 2;private MIDDEN_INDEX: number = 1;private HEAD_INDEX: number = 0;getImageResource(current: number, mIndex: number) {let currentPage: string | Resource = ''if (current == this.END_INDEX) {if (mIndex == this.HEAD_INDEX) {currentPage = this.mImageResource[2];} else if (mIndex == this.MIDDEN_INDEX) {currentPage = this.mImageResource[0];} else if (mIndex == this.END_INDEX) {currentPage = this.mImageResource[1];}} else if (current == this.MIDDEN_INDEX) {if (mIndex >= 2) {currentPage = this.mImageResource[0];} else {currentPage = this.mImageResource[mIndex+1];}} else if (current == this.HEAD_INDEX) {currentPage = this.mImageResource[this.mIndex];}return currentPage;}private monAnimationEndCallBack = (): void => {this.mLayerOpacity = 0.9;}private monChangeCallBack = (index: number): void => {this.mIndex = index;this.mCardOpacity = this.CARD_ANIM_START;this.mLayerOpacity = this.LAYER_CARD_ANIM_START;setTimeout(() => {this.mCardOpacity = this.CARD_ANIM_END;this.mLayerOpacity = this.LAYER_CARD_ANIM_END;}, 100);}EndLayerView() {Row() {Blank()Image(this.getImageResource(this.END_INDEX, this.mIndex)).width(px2vp(500)).height(px2vp(600)).opacity(this.mLayerOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Black)}.width(px2vp(1000)).height(px2vp(800))}MiddenLayerView() {Row() {Blank()Image(this.getImageResource(this.MIDDEN_INDEX, this.mIndex)).width(px2vp(400)).height(px2vp(700)).opacity(this.mLayerOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Red)}.width(px2vp(800)).height(px2vp(800))}HeadCard() {Row() {if (this.HEAD_INDEX == this.mIndex) {Image(this.mImageResource[this.HEAD_INDEX]).BGCardCardWidthAndHeight().opacity(this.mCardOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Blue)}}.BGWidthAndHeight()}MiddenCard() {Row() {if (this.MIDDEN_INDEX == this.mIndex) {Image(this.mImageResource[this.MIDDEN_INDEX]).BGCardCardWidthAndHeight().opacity(this.mCardOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Blue)}}.BGWidthAndHeight()}EndCard() {Row() {if (this.END_INDEX == this.mIndex) {Image(this.mImageResource[this.END_INDEX]).BGCardCardWidthAndHeight().opacity(this.mCardOpacity).CardAnim().borderWidth(px2vp(2)).borderColor(Color.Red).backgroundColor(Color.Blue)}}.BGWidthAndHeight()}HeadSwiperLayerView() {Swiper(this.swiperController) {this.HeadCard()this.MiddenCard()this.EndCard()}.loop(true).autoPlay(true).indicator(false).duration(500).curve(Curve.Friction).displayMode(SwiperDisplayMode.STRETCH).onChange(this.monChangeCallBack).onAnimationEnd(this.monAnimationEndCallBack)}BGWidthAndHeight(){.width(this.BG_WIDTH).height(this.BG_HEIGHT)}BGCardCardWidthAndHeight(){.width(this.BG_CARD_WIDTH).height(this.BG_CARD_HEIGHT).borderWidth(px2vp(2)).borderColor(Color.Red)}CardAnim(){.animation({duration: 1000,tempo: 1,delay: 0,curve: Curve.Friction,playMode: PlayMode.Normal,iterations: 1})}build() {Stack({ alignContent: Alignment.Center }) {// 最底层卡片this.EndLayerView()// 中间层卡片this.MiddenLayerView()// 最上层swiper滑动层this.HeadSwiperLayerView()}}
}

入口界面类
Index.ets

import SlidingCardView from './SlidingCardView'

struct Index {build() {Column(){SlidingCardView()}.width("100%").height("100%")}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/63263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python_Flask02

所有人都不许学Java了&#xff0c;都来学Python&#xff01; 如果不来学的话请网爆我的老师 连接前的准备 安装pymysql 和 flask_sqlalchemy&#xff0c;安装第三下面两个所需要的包才能连接上数据库 pip install pymysql pip install flask_sqlalchemy pymysql是一个Pyth…

实验13 使用预训练resnet18实现CIFAR-10分类

1.数据预处理 首先利用函数transforms.Compose定义了一个预处理函数transform&#xff0c;里面定义了两种操作&#xff0c;一个是将图像转换为Tensor&#xff0c;一个是对图像进行标准化。然后利用函数torchvision.datasets.CIFAR10下载数据集&#xff0c;这个函数有四个常见的…

linux下使用gdb运行程序,查看程序崩溃原因

1.什么是gdb? gdb 是 GNU Debugger 的缩写&#xff0c;是一个功能强大的用于调试程序的开源调试器工具。它可以帮助开发人员诊断和解决程序中的错误、跟踪程序执行过程、查看变量的值等。gdb 支持多种编程语言&#xff0c;包括 C、C、Objective-C、Fortran 等&#xff0c;并可…

鸿蒙arkts怎么打印一个方法的调用堆栈

做鸿蒙开发的时候&#xff0c;也想看一下一个方法到底是哪里调用的&#xff0c;工程太大&#xff0c;断点太麻烦&#xff0c;可以加堆栈日志。 在你的方法中加上这两句&#xff0c;就可以跟到堆栈日志 let err new Error() console.log(>>>>>>err.stack) …

IDE如何安装插件实现Go to Definition

项目背景 框架&#xff1a;Cucumber Cypress 语言&#xff1a;Javascript IDE&#xff1a;vscode 需求 项目根目录cypress-automation的cypress/integration是测试用例的存放路径&#xff0c;按照不同模块不同功能创建了很多子目录&#xff0c;cucumber测试用例.feature文…

如何通过 Windows 自带的启动管理功能优化电脑启动程序

在日常使用电脑的过程中&#xff0c;您可能注意到开机后某些程序会自动运行。这些程序被称为“自启动”或“启动项”&#xff0c;它们可以在系统启动时自动加载并开始运行&#xff0c;有时甚至在后台默默工作。虽然一些启动项可能是必要的&#xff08;如杀毒软件&#xff09;&a…

探索自然语言处理奥秘(NLP)

摘要 自然语言处理&#xff08;NLP&#xff09;是人工智能领域的一个重要分支&#xff0c;它致力于使计算机能够理解、解释和生成人类语言。这项技术让机器能够阅读文本、听懂语音&#xff0c;并与人类进行基本的对话交流。 通俗理解 自然语言处理&#xff08;NLP&#xff09…

# issue 8 TCP内部原理和UDP编程

TCP 通信三大步骤&#xff1a; 1 三次握手建立连接; 2 开始通信&#xff0c;进行数据交换; 3 四次挥手断开连接&#xff1b; 一、TCP内部原理--三次握手 【第一次握手】套接字A∶"你好&#xff0c;套接字B。我这儿有数据要传给你&#xff0c;建立连接吧。" 【第二次…

力扣--543.二叉树的直径

题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 代码 /** Definition for a binary tree node.public…

在ensp进行IS-IS网络架构配置

一、实验目的 1. 理解IS-IS协议的工作原理 2. 熟练ensp路由连接配置 二、实验要求 需求&#xff1a; 路由器可以互相ping通 实验设备&#xff1a; 路由器router6台 使用ensp搭建实验坏境&#xff0c;结构如图所示 三、实验内容 R1 u t m sys undo info en sys R1 #设…

挑战用React封装100个组件【010】

Hello&#xff0c;大家好&#xff0c;今天我挑战的组件是这样的&#xff01; 今天这个组件是一个打卡成功&#xff0c;或者获得徽章后的组件。点击按钮后&#xff0c;会弹出礼花。项目中的勋章是我通过AI生成的&#xff0c;还是很厉害的哈&#xff01;稍微抠图直接使用。最后面…

Mybatis-Plus的主要API

一、实体类操作相关API BaseMapper<T>接口 功能&#xff1a;这是 MyBatis - Plus 为每个实体类对应的 Mapper 接口提供的基础接口。它提供了一系列基本的 CRUD&#xff08;增删改查&#xff09;操作方法。例如insert(T entity)方法用于插入一条记录&#xff0c;d…

C++类与对象(二)

一、默认成员函数 class A{}; 像上面一样&#xff0c;一个什么都没有的类叫做空类&#xff0c;但是这个什么都没有并不是真正的什么都没有&#xff0c;只是我们看不见&#xff0c;空类里面其实是有6个默认成员函数的&#xff0c;当我们在类里面什么都不写的时候&#xff0c;编译…

数据结构与算法-03链表-03

递归与迭代 由一个问题引出 假设我们要计算 一个正整数的阶乘, N! 。 从数学上看 1&#xff01; 1 2&#xff01; 2 x 1 3! 3 x 2 x 1 4! 4 x 3 x 2 x 1 5! 5 x 4 x 3 x 2 x 1 : n! n x (n-1) x (n-2) x (n-3) x ... 1我们推出一般公式 f(1) 1 f(n) n * f(n-1…

spring6:2入门

spring6&#xff1a;2入门 目录 spring6&#xff1a;2入门2.1、环境要求2.2、构建模块2.3、程序开发2.3.1、引入依赖2.3.2、创建java类2.3.3、创建配置文件2.3.4、创建测试类测试2.3.5、运行测试程序 2.4、程序分析2.5、启用Log4j2日志框架2.5.1、Log4j2日志概述2.5.2、引入Log…

汽车IVI中控开发入门及进阶(三十五):架构QML App Architecture Best Practices

在Qt/QML工程的架构中,架构很重要,虽然本身它有分层,比如QML调用资源文件(图片等)显示GUI界面,后面的CPP文件实现界面逻辑,但是这个分类还有点粗。在实际开发中,界面逻辑也就是基于类cpp的实现,也开始使用各种面向对象的设计模式,实现更加优秀的开发架构,这点尤其在…

import是如何“占领满屏“

import是如何“占领满屏“的&#xff1f; 《拒绝使用模块重导&#xff08;Re-export&#xff09;》 模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。 如&#xff1a;字节的arco-design组件库中的组件&#xff1a;github.com/arco-design… …

(软件测试文档大全)测试计划,测试报告,测试方案,压力测试报告,性能测试,等保测评,安全扫描测试,日常运维检查测试,功能测试等全下载

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

抽象工厂模式的理解和实践

在软件开发中&#xff0c;设计模式是解决常见问题的最佳实践。抽象工厂模式是一种创建型设计模式&#xff0c;提供了一种创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们的具体类。本文将详细解释抽象工厂模式的概念、结构、优点、缺点&#xff0c;并通过Java代…

算法日记(2024.12.05)

1.对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&#xff1…