鸿蒙ArkTs开发,仿抖音个人中心header 下拉放大

如果是iOS 或者android 上实现,可以用Scollview 的contentOffset 来实现,然而在鸿蒙ets中该如何实现?废话不多说开始撸代码

第一步、实现一个header

// 创建header,准备一张背景图片
  @Builder
  HeaderBuilder(){
    Column() {
      Row() {
        Image($r('app.media.back'))
          .width(25)
          .height(25)
          .onClick(() => {
            router.back();
          })
        Text(this.distance == 0 ? 'test1' : "")
          .fontColor(Color.Black)
          .fontSize(20)
          .margin({ left: 5 })
        Blank()
        Image($r('app.media.share'))
          .width(25)
          .height(25)

        Image($r('app.media.more'))
          .width(25)
          .height(25)

      }
      .width('100%')
      .padding(20)
      .margin({ top: 20 })

      Row() {
        Text(this.distance > 0 ? 'test2' : '')
          .fontColor(Color.Red)
          .fontSize(30)
          .margin({ left: 5 })
      }
      .width("100%")
      .height(35)
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Start)
    }
    .height(this.ImHeight)
    .width(this.ImWidth)
    .align(Alignment.Center)
    .backgroundImage($r('app.media.banner'))
    .backgroundImageSize(ImageSize.Cover)
  }

 第二步、创建header下方的内容部分,通过下拉下面的部分来实现header 背景图放大,松开后复原

这里小编通过TouchEvent 事件来实现具体代码如下:

.onTouch((event: TouchEvent) => {
        var y = event.touches[0].y
        if (event.type === TouchType.Down) {
          this.duration = 1000;
          this.startY = y;

        }
        if (event.type === TouchType.Up) {
          this.duration = 500;
          this.ImHeight = 200
          this.ImWidth = "100%"
          this.distance = 0
        }
        if (event.type === TouchType.Move) {
          this.distance = event.touches[0].y - this.startY
          if (Math.abs(this.distance) <= 100) {
            console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
            var height = 200 + this.distance
            if (height <= 0) {
              height = 0
            }else {
              var scale = this.distance / 200;
              this.ImHeight = height
              console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
              var imgWidth = 100 + scale * 100 + '%'
              if (100 + scale * 100 < 100){
                imgWidth = '100%'
                this.offX = -25 + this.distance
              }else {
                this.offX = -25
              }
              this.ImWidth = imgWidth
            }
          }else{
            this.distance = 0
          }
        }
      })

然而只有手势虽然能实现滑动,但是效果不好,没有bounce 感!如何让他有bounce 感?需要使用动画,具体代码如下:

.animation({
        duration: this.duration,
        curve: Curve.FastOutSlowIn,
        delay: 0,
        iterations: 1,
        playMode: PlayMode.Normal
      })

以上代码基本上是实现本功能的核心部分,完整的代码如下:

// 可拖动子组件,动画,圆弧
      Column() {
        Row() {
          Text('当点击此场景卡片时:')
            .fontSize(16)
          Blank()
          Image($r('app.media.menu'))
            .width(30)
            .height(30)
        }
        .width('100%')
        .margin({ top: 10, left: 10, right: 10, bottom: 20 })
      }
      .offset({y: this.offX})
      .borderRadius(35)
      .padding(20)
      .onTouch((event: TouchEvent) => {
        var y = event.touches[0].y
        if (event.type === TouchType.Down) {
          this.duration = 1000;
          this.startY = y;

        }
        if (event.type === TouchType.Up) {
          this.duration = 500;
          this.ImHeight = 200
          this.ImWidth = "100%"
          this.distance = 0
        }
        if (event.type === TouchType.Move) {
          this.distance = event.touches[0].y - this.startY
          if (Math.abs(this.distance) <= 100) {
            console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
            var height = 200 + this.distance
            if (height <= 0) {
              height = 0
            }else {
              var scale = this.distance / 200;
              this.ImHeight = height
              console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
              var imgWidth = 100 + scale * 100 + '%'
              if (100 + scale * 100 < 100){
                imgWidth = '100%'
                this.offX = -25 + this.distance
              }else {
                this.offX = -25
              }
              this.ImWidth = imgWidth
            }
          }else{
            this.distance = 0
          }
        }
      })
      .height('100%')
      .animation({
        duration: this.duration,
        curve: Curve.FastOutSlowIn,
        delay: 0,
        iterations: 1,
        playMode: PlayMode.Normal
      })
      .linearGradient(
        {
          direction: GradientDirection.Top,
          angle: 180,
          colors: [['#c7e2eb', 0.01], ["#F7F7F7", 0.05], ["#F7F7F7", 1]]
        })
     }
    .justifyContent(FlexAlign.Start)

下面是本案列的全部代码,仅供参考:

@Preview
@Entry
@Component
struct DetailPage {
  @State duration: number = 1000
  @State ImHeight: number = 200
  @State ImWidth: string = '100%'
  @State distance: number = 0
  @State offX: number = -25
  private startY = 0

  // 创建header,准备一张背景图片
  @Builder
  HeaderBuilder(){
    Column() {
      Row() {
        Image($r('app.media.back'))
          .width(25)
          .height(25)
          .onClick(() => {
            router.back();
          })
        Text(this.distance == 0 ? 'test1' : "")
          .fontColor(Color.Black)
          .fontSize(20)
          .margin({ left: 5 })
        Blank()
        Image($r('app.media.share'))
          .width(25)
          .height(25)

        Image($r('app.media.more'))
          .width(25)
          .height(25)

      }
      .width('100%')
      .padding(20)
      .margin({ top: 20 })

      Row() {
        Text(this.distance > 0 ? 'test2' : '')
          .fontColor(Color.Red)
          .fontSize(30)
          .margin({ left: 5 })
      }
      .width("100%")
      .height(35)
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.Start)
    }
    .height(this.ImHeight)
    .width(this.ImWidth)
    .align(Alignment.Center)
    .backgroundImage($r('app.media.banner'))
    .backgroundImageSize(ImageSize.Cover)
  }


  build() {
    Column() {
      // header
      this.HeaderBuilder()
      // 可拖动子组件,动画,圆弧
      Column() {
        Row() {
          Text('当点击此场景卡片时:')
            .fontSize(16)
          Blank()
          Image($r('app.media.menu'))
            .width(30)
            .height(30)
        }
        .width('100%')
        .margin({ top: 10, left: 10, right: 10, bottom: 20 })
      }
      .offset({y: this.offX})
      .borderRadius(35)
      .padding(20)
      .onTouch((event: TouchEvent) => {
        var y = event.touches[0].y
        if (event.type === TouchType.Down) {
          this.duration = 1000;
          this.startY = y;

        }
        if (event.type === TouchType.Up) {
          this.duration = 500;
          this.ImHeight = 200
          this.ImWidth = "100%"
          this.distance = 0
        }
        if (event.type === TouchType.Move) {
          this.distance = event.touches[0].y - this.startY
          if (Math.abs(this.distance) <= 100) {
            console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
            var height = 200 + this.distance
            if (height <= 0) {
              height = 0
            }else {
              var scale = this.distance / 200;
              this.ImHeight = height
              console.log("height=>"+ this.ImHeight +  "distance= ", this.distance)
              var imgWidth = 100 + scale * 100 + '%'
              if (100 + scale * 100 < 100){
                imgWidth = '100%'
                this.offX = -25 + this.distance
              }else {
                this.offX = -25
              }
              this.ImWidth = imgWidth
            }
          }else{
            this.distance = 0
          }
        }
      })
      .height('100%')
      .animation({
        duration: this.duration,
        curve: Curve.FastOutSlowIn,
        delay: 0,
        iterations: 1,
        playMode: PlayMode.Normal
      })
      .linearGradient(
        {
          direction: GradientDirection.Top,
          angle: 180,
          colors: [['#c7e2eb', 0.01], ["#F7F7F7", 0.05], ["#F7F7F7", 1]]
        })
     }
    .justifyContent(FlexAlign.Start)
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

社交媒体数据恢复:爱聊

爱聊数据恢复方法 在爱聊的使用过程中&#xff0c;如果遇到数据丢失的情况&#xff0c;可以尝试以下几种方法来恢复数据。 1. 硬盘坏道检测与修复 如果问题是由于硬盘坏道导致的&#xff0c;可以按照以下步骤进行操作&#xff1a; 找到需要修复的坏道磁盘&#xff1a;首先&…

js模块化:修改导入模块的内容,会有影响吗?

起因 element-ui的popper组件相关的层级&#xff0c;是使用popup-manager来统一管理的。 之前试图在自己的组件里导入并使用element-ui的popup-manager&#xff0c;但是层级老是和element-ui组件的层级冲突&#xff0c;看了下源码&#xff0c;竟意外发现&#xff0c;使用popu…

基于若依框架搭建网站的开发日志(一):若依框架搭建、启动、部署

RuoYi&#xff08;基于SpringBoot开发的轻量级Java快速开发框架&#xff09; 链接&#xff1a;开源地址 若依是一款开源的基于VueSpringCloud的微服务后台管理系统&#xff08;也有SpringBoot版本&#xff09;&#xff0c;集成了用户管理、权限管理、定时任务、前端表单生成等…

You don’t have permission.

The document “XXX” could not be saved. You don’t have permission. 1.查看修改了iOS系统库导致的, 根据提示, 进入到"XXX"文件中, 然后commandz回退/取消 2. Xcode 调试遇到的报错&#xff08;持续更新&#xff09;

治疗耳鸣患者案例分享第二期

“患者耳鸣20年了&#xff0c;目前耳朵没有堵或者胀的感觉&#xff0c;但是偶尔有点痒&#xff0c;平时会有头晕头胀这种情况&#xff0c;然后头晕是稍微晕炫一下。然后头疼是经常有的&#xff0c;头胀不经常。” 患者耳鸣持续20年&#xff0c;虽然耳朵没有堵或胀的感觉&#x…

书生浦语训练营第三次课笔记:XTuner 微调 LLM:1.8B、多模态、Agent

Finetune 简介 两种Finetune范式&#xff1a;增量预训练微调、指令跟随微调 微调数据集 上述是我们所期待模型回答的内容&#xff0c;在训练时损失的计算也是基于这个。 训练数据集看起来是这样&#xff0c;但是真正喂给模型的&#xff0c;是经过对话模板组装后的 下图中&…

防火墙的基本概念

我们在 TCP/IP协议四层模型与OSI七层模型 的最后说过&#xff0c;在四层模型中每一层都会有对应的风险&#xff0c;而防火墙就是来阻断这些风险的工具。 防火墙的基本功能 防火墙的分类 目前没有权威而明确的分类 按照实现方式&#xff1a; 硬件防火墙软件防火墙 按照部署…

HNU-人工智能-实验1-A*算法

人工智能-实验1 计科210x 甘晴void 一、实验目的 掌握有信息搜索策略的算法思想&#xff1b; 能够编程实现搜索算法&#xff1b; 应用A*搜索算法求解罗马尼亚问题。 二、实验平台 课程实训平台https://www.educoder.net/shixuns/vgmzcukh/challenges 三、实验内容 3.…

高扬程水泵助力森林消防,守护绿色生命线/恒峰智慧科技

随着人类社会的不断发展&#xff0c;森林资源的保护和管理变得越来越重要。然而&#xff0c;森林火灾却时常威胁着这一宝贵资源。为了有效应对森林火灾&#xff0c;提高灭火效率&#xff0c;高扬程水泵在森林消防中发挥了重要作用。本文将重点介绍高扬程水泵在森林消防中的应用…

AI终端设备的自动化分级

摘要&#xff1a; AI智体被定义为感知环境、做出决策和采取行动的人工实体。 受SAE&#xff08;汽车工程师学会&#xff09;自动驾驶6个级别的启发&#xff0c;AI智体也根据效用和强度进行分类&#xff0c;分为以下几个级别&#xff1a; L0——无AI&#xff0c;有工具&#xf…

机器学习中线性回归算法的推导过程

线性回归是机器学习中监督学习中最基础也是最常用的一种算法。 背景&#xff1a;当我们拿到一堆数据。这堆数据里有参数&#xff0c;有标签。我们将这些数据在坐标系中标出。我们会考虑这些数据是否具有线性关系。简单来说 我们是否可以使用一条线或者一个平面去拟合这些数据的…

力扣每日一题111:二叉树的最小深度

题目 简单 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2示例 2&#x…

SpringCloud生态体系介绍

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。 必要说…

【面试经典 150 | 图】除法求值

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;广度优先搜索 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容…

2024年第二十六届“华东杯”(B题)大学生数学建模挑战赛|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看华东杯 (B题&#xff09;&#xff01; 第一个问题…

CI/CD笔记.Gitlab系列.新用户管理

CI/CD笔记.Gitlab系列 新用户管理 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_285502…

使用CNN或resnet,分别在flower5,flower17,flower102数据集上实现花朵识别分类-附源码-免费

前言 使用cnn和resnet实现了对flower5&#xff0c;flower17&#xff0c;flower102数据集上实现花朵识别分类。也就是6份代码&#xff0c;全部在Gitee仓库里&#xff0c;记得点个start支持谢谢。 本文给出flower17在cnn网络实现&#xff0c;flower102在resnet网络实现的代码。…

正则表达式-前瞻和后顾

正则表达式中的前瞻和后顾。 前瞻(Lookahead) 前瞻是一种断言,它会检查在当前位置之后是否存在某种模式,但不会实际匹配该模式。前瞻有两种形式: 正向前瞻 (?pattern) 检查当前位置之后是否存在指定的模式如果存在,则匹配成功,但不会消耗该模式例如 \w(?\d) 将匹配后面跟数…

Mysql 8.0.33 迁移至 Postgresql 16.2

小伙伴们&#xff0c;你们好&#xff0c;我是老寇&#xff0c;我又回来&#xff0c;几个月不见&#xff0c;甚是想念啊&#xff01;&#xff01;&#xff01;&#xff01; 这不&#xff0c;云平台需要改造&#xff0c;将Mysql替换成Postgresql&#xff0c;话说回来&#xff0c…

步态识别论文(6)GaitDAN: Cross-view Gait Recognition via Adversarial Domain Adaptation

摘要: 视角变化导致步态外观存在显着差异。因此&#xff0c;识别跨视图场景中的步态是非常具有挑战性的。最近的方法要么在进行识别之前将步态从原始视图转换为目标视图&#xff0c;要么通过蛮力学习或解耦学习提取与相机视图无关的步态特征。然而&#xff0c;这些方法有许多约…