资讯专栏INFORMATION COLUMN

ReactNative: 使用Animted API实现向上滚动时隐藏Header组件

Aklman / 2476人阅读

摘要:只能自己上了思路很清楚监听滚动事件,动态修改组件和组件的值当然,他们默认都是。插值对输入范围和输出范围之间做一个映射,通常使用线性插值,但也支持缓和函数。

想先推荐一下近期在写的一个React Native项目,名字叫 Gakki :是一个Mastodon的第三方客户端 (Android App)

预览

写在前面

本来我也不想造这个轮子的,奈何没找到合适的组件。只能自己上了~

思路很清楚: 监听滚动事件,动态修改Header组件和Content组件的top值(当然,他们默认都是position:relative)。

接下来实现的时候遇到了问题,我第一个版本是通过动态设置state来实现,即:

/**
 * 每次滚动时,重新设置headerTop的值
 */
onScroll = event =>{
    const y = event.nativeEvent.contentOffset.y
    if (y >= 270) return
    // headerTop即是Header和Content的top样式对应的值
    this.setState({
        headerTop: y
    })
}

这样虽然能实现,但是效果不好:明显可以看到在上滑的过程中,Header组件一卡一卡地向上方移动(一点都不流畅)。

因为就只能另寻他法了:动画

React Native 提供了两个互补的动画系统:用于创建精细的交互控制的动画Animated和用于全局的布局动画LayoutAnimation (笔者注:这次没有用到它)
Animated 相关API介绍

首先,这儿有一个简单“逐渐显示”动画的DEMO,需要你先看完(文档很简单明了且注释清楚,没必要Copy过来)。

在看懂了DEMO的基础上,我们还需要了解两个关键的API才能实现完整的效果:

1. interpolate

插值函数。用来对不同类型的数值做映射处理。

当然,这是文档说明:

Each property can be run through an interpolation first. An interpolation maps input ranges to output ranges, typically using a linear interpolation but also supports easing functions. By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.

翻译:

每个属性可以先经过插值处理。插值对输入范围和输出范围之间做一个映射,通常使用线性插值,但也支持缓和函数。默认情况下,如果给定数据超出范围,他也可以自行推断出对于的曲线,但您也可以让它箝位输出值(P.S. 最后一句可能翻译错误,因为没搞懂clamp value指的是什么, sigh...)

举个例子:

在实现一个图片旋转动画时,输入值只能是这样的:

this.state = {
  rotate: new Animated.Value(0) // 初始化用到的动画变量
}

...

// 这么映射是因为style样式需要的是0deg这样的值,你给它0这样的值,它可不能正常工作。因为必定需要一个映射处理。
this.state.rotate.interpolate({ // 将0映射成0deg,1映射成360deg。当然中间的数据也是如此映射。
  inputRange: [0, 1],
  outputRange: ["0deg", "360deg"]
})

2. Animated.event

一般动画的输入值都是默认设定好的,比如前面DEMO中的逐渐显示动画中的透明度:开始是0,最后是1。这是已经写死了的。

但如果有些动画效果需要的不是写死的值,而是动态输入的呢,比如:手势(上滑、下滑,左滑,右滑...)、其它事件。

那就用到了Animated.event

直接看一个将滚动事件的y值(滚动条距离顶部高度)和我们的动画变量绑定起来的例子:

// 这段代码表示:在滚动事件触发时,将event.nativeEvent.contentOffset.y 的值动态绑定到this.state.headerTop上
// 和最前面我通过this.setState动态设置的目的一样,但交给Animated.event做就不会造成视觉上的卡顿了。
onScroll={Animated.event([
   {
      nativeEvent: {
        contentOffset: { y: this.state.headerTop }
      }
   }
])}

关于API更多的说明请移步文档

完整代码
import React, { Component } from "react"
import { StyleSheet, Text, View, Animated, FlatList } from "react-native"

class List extends Component {
  render() {
    // 模拟列表数据
    const mockData = [
      "富强",
      "民主",
      "文明",
      "和谐",
      "自由",
      "平等",
      "公正",
      "法治",
      "爱国",
      "敬业",
      "诚信",
      "友善"
    ]

    return (
       (
          
            {item}
          
        )}
      />
    )
  }
}

export default class AnimatedScrollDemo extends Component {
  constructor(props) {
    super(props)
    this.state = {
      headerTop: new Animated.Value(0)
    }
  }

  componentWillMount() {
    // P.S. 270,217,280区间的映射是告诉interpolate,所有大于270的值都映射成-50
    // 这样就不会导致Header在上滑的过程中一直向上滑动了
    this.top = this.state.headerTop.interpolate({
      inputRange: [0, 270, 271, 280],
      outputRange: [0, -50, -50, -50]
    })

    this.animatedEvent = Animated.event([
      {
        nativeEvent: {
          contentOffset: { y: this.state.headerTop }
        }
      }
    ])
  }

  render() {
    return (
      
        
          
            linshuirong.cn
          
        
        {/* 在oHeader组件上移的同时,列表容器也需要同时向上移动,需要注意。 */}
        
          
        
      
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  list: {
    height: 80,
    backgroundColor: "pink",
    marginBottom: 1,
    alignItems: "center",
    justifyContent: "center",
    color: "white"
  },
  header: {
    height: 50,
    backgroundColor: "#3F51B5",
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    color: "white"
  }
})

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100389.html

相关文章

  • 推荐三两款前端动画库,anitmate.css, velocity-animate, anime,

    摘要:所以就说说吧优点可自定义动画效果,支持队列动效支持回调函数支持动画的,等等功能缺点缺少自定义特效文档比较少使用遇到的小问题默认不是匀速的,需要设置详细整理待续 在最近一段时间的工作里,常常用到动画,我主要接触了三个 animate.cssanimevelocity 下面分析一下他们的优缺点 animate.css 优点:animate.css主要是使用css实现动画效果,目前已经有几十...

    xzavier 评论0 收藏0
  • 从入门到上线一个天气小程序

    摘要:天气预报小程序说了很多小程序开发的基础准备,下面就结合个人实际练手项目天气预报小程序简单说明。物料准备从需求结果导向,天气程序首先要能获取到当前所在地天气状况,再次可以自由选择某地,知道其天气状况。 前言 学习了一段时间小程序,大致过了两遍开发文档,抽空做个自己的天气预报小程序,全当是练手,在这记录下。小程序开发的安装、注册和接入等流程就不罗列了,在小程序接入指南已经写得很清楚了,以下...

    Anshiii 评论0 收藏0
  • Making An Indicator With Pure CSS

    摘要:注意此处的定位是以即的外沿框进行定位的。关于单位,这个单位代表的意思即,即浏览器可视区域的高度。,我们现在来看效果将会是下面这张图片显示的样子。设置目的即让的高度为,即到顶部的距离减去的距离。 简单的说明一下,使用这个标题并不就是说要使用全英文来写这篇文章,主要是实在想不到更好的叫法了,也不知道怎么样能够更好的翻译成中文。 可以简单地理解为:使用 CSS 来实现一个阅读文章时的简单的...

    church 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<