native固定吸顶 react_【react-native】滑动吸顶效果 + 下拉刷新

现象:最近开发RN项目,需要开发一个页面滑动过程中的tab吸顶的效果。

解决方案: 使用Animated创建动画

具体代码如下:

index.tsx

import React, { Component } from 'react'

import { View, Text, ViewStyle, StyleSheet, ImageBackground, Animated, RefreshControl } from 'react-native'

import StickyHeader from "./StickyHeader"

import { images, dimensions } from '../../../../res'

interface IState {

refreshing: boolean,

scrollHeight: number,

scrollY: Animated.Value

}

export class PrivateCollectScreen extends Component {

readonly state: IState = {

scrollY: new Animated.Value(0),

scrollHeight: -1,

refreshing: false

}

render() {

return (

style={{ flex: 1 }}

onScroll={

Animated.event( // 映射动画值

[{

// 垂直滚动时,将 event.nativeEvent.contentOffset.y映射到this.state.scrollY,以此记录滑动距离

nativeEvent: { contentOffset: { y: this.state.scrollY } }

}],

{ useNativeDriver: true }) // 启用原生动画驱动。默认不启用(false)

}

scrollEventThrottle={1} // 滚动条距离视图边缘的坐标

refreshControl={ // 下拉刷新功能

style={{ backgroundColor: 'transparent' }}

tintColor={'white'}

refreshing={this.state.refreshing}

onRefresh={() => { // 再刷新时调用

this.setState({ refreshing: true })

}} />

}

>

{

this.setState({ scrollHeight: e.nativeEvent.layout.height }) // 获取头部的高度

}}>

style={{ width: dimensions.screenWidth, height: 190 }}

source={images.icReact}

>

{/* 头部内容 */}

stickyHeaderY={this.state.scrollHeight} // 将头部高度传入组件

stickyScrollY={this.state.scrollY} // 将滑动距离传入组件

>

固定栏

{/* 底部内容 */}

{

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((item, index) => {

return (底部内容{index})

})

}

)

}

}

interface Styles {

container: ViewStyle

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff'

}

})

StickyHeader.tsx

import * as React from 'react'

import { StyleSheet, Animated } from 'react-native'

interface IState {

stickyLayoutY: number,

stickyHeaderY: number,

stickyScrollY: Animated.Value

}

/**

* 滑动吸顶效果组件

* @export

* @class StickyHeader

*/

export default class StickyHeader extends React.Component {

readonly state: IState = {

stickyHeaderY: -1,

stickyScrollY: new Animated.Value(0),

stickyLayoutY: 0

}

// 兼容代码,防止没有传头部高度

_onLayout = (event) => {

this.setState({

stickyLayoutY: event.nativeEvent.layout.y,

})

}

render() {

const { stickyHeaderY, stickyScrollY, children, style } = this.props

const { stickyLayoutY } = this.state

let y = stickyHeaderY !== -1 ? stickyHeaderY : stickyLayoutY

const translateY = stickyScrollY.interpolate({

inputRange: [-1, 0, y, y + 1],

outputRange: [0, 0, 0, 1],

})

return (

onLayout={this._onLayout}

style={

[

style,

styles.container,

{ transform: [{ translateY }] }

]}

>

{children}

)

}

}

const styles = StyleSheet.create({

container: {

zIndex: 100

}

})

效果图

效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值