有什么办法使本机ScrollView onScroll钩子产生动画? [英] Is there any way to animate with react native ScrollView onScroll hooks?

查看:84
本文介绍了有什么办法使本机ScrollView onScroll钩子产生动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将类的基础组件转换为用于动画的功能基础组件. https://snack.expo.io/@wyrustaaruz/animation-test-基于课程的

I want to convert the class base component to the functional base component for animation. https://snack.expo.io/@wyrustaaruz/animation-test-class-base

您可以使用小吃链接来更改代码. 您也可以在下面的行中查看代码. 这段代码在基于类的基础组件上运行良好.

You can use snack link for changing code. also you can look code below lines. This code works well on class base component.

我尝试了useRef,useState,但无法解决此问题.

I tried useRef, useState but I couldn't solve this problem.

这是我的功能基础链接:

This is the my functional base link:

https://snack.expo.io/@wyrustaaruz/animated -with-function-base

import React, {Component} from 'react';
import {
  Animated,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

const HEADER_MAX_HEIGHT = 200;
const HEADER_MIN_HEIGHT = 60;
const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;

export default class ScrollableHeader extends Component {
  constructor(props) {
  super(props);

  this.state = {
    scrollY: new Animated.Value(0),
  };
}
  _renderScrollViewContent() {
    const data = Array.from({length: 30});
    return (
      <View style={styles.scrollViewContent}>
        {data.map((_, i) =>
          <View key={i} style={styles.row}>
            <Text>{i}</Text>
          </View>
        )}
      </View>
    );
  }

  render() {
     const headerHeight = this.state.scrollY.interpolate({
    inputRange: [0, HEADER_SCROLL_DISTANCE],
    outputRange: [0, 1],
    extrapolate: 'clamp',
  });
    return (
      <View style={styles.fill}>
        <ScrollView
    style={styles.fill}
    scrollEventThrottle={16}
    onScroll={Animated.event(
      [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
    )}
  >
          {this._renderScrollViewContent()}
        </ScrollView>
        <Animated.View opacity={headerHeight} style={[styles.header]}>
          <View style={styles.bar}>
            <Text style={styles.title}>Title</Text>
          </View>
        </Animated.View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  fill: {
    flex: 1,
  },
  row: {
    height: 40,
    margin: 16,
    backgroundColor: '#D3D3D3',
    alignItems: 'center',
    justifyContent: 'center',
  },
  header: {
  position: 'absolute',
  top: 0,
  left: 0,
  right: 0,
  backgroundColor: '#03A9F4',
  overflow: 'hidden',
},
bar: {
  marginTop: 28,
  height: 32,
  alignItems: 'center',
  justifyContent: 'center',
},
title: {
  backgroundColor: 'transparent',
  color: 'white',
  fontSize: 18,
},
scrollViewContent: {
  marginTop: 0,
},
});

推荐答案

在这里;)

请记住,您必须使用Animated.ScrollView才能使事件正常运行.

Mind you, you have to use Animated.ScrollView in order for the event to work correctly.

这是更新的小吃链接: https ://snack.expo.io/@milt/animated-base-with-functional-component-and-hooks

Here is the updated snack link: https://snack.expo.io/@milt/animated-base-with-functional-component-and-hooks

以及以下代码:


    import React, { useRef } from 'react';
    import PropTypes from 'prop-types';
    import { View, Text, StyleSheet, Animated } from 'react-native';

    const HEADER_MAX_HEIGHT = 200;
    const HEADER_MIN_HEIGHT = 60;
    const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;

    const styles = StyleSheet.create({
      fill: {
        flex: 1,
      },
      row: {
        height: 40,
        margin: 16,
        backgroundColor: '#D3D3D3',
        alignItems: 'center',
        justifyContent: 'center',
      },
      header: {
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: '#03A9F4',
        overflow: 'hidden',
      },
      bar: {
        marginTop: 28,
        height: 32,
        alignItems: 'center',
        justifyContent: 'center',
      },
      title: {
        backgroundColor: 'transparent',
        color: 'white',
        fontSize: 18,
      },
      scrollViewContent: {
        marginTop: 0,
      },
    });

    const data = Array.from({ length: 30 });

    const ScrollableHeader = () => {
      const animatedScrollYValue = useRef(new Animated.Value(0)).current;

      const headerHeight = animatedScrollYValue.interpolate({
        inputRange: [0, HEADER_SCROLL_DISTANCE],
        outputRange: [0, 1],
        extrapolate: 'clamp',
      });

      return (
        <View style={styles.fill}>
          <Animated.ScrollView
            style={styles.fill}
            contentContainerStyle={styles.scrollViewContent}
            scrollEventThrottle={16}
            onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: animatedScrollYValue } } }])}
          >
            <View style={styles.scrollViewContent}>
              {data.map((_, i) => (
                <View key={i} style={styles.row}>
                  <Text>{i}</Text>
                </View>
              ))}
            </View>
          </Animated.ScrollView>
          <Animated.View opacity={headerHeight} style={[styles.header]}>
            <View style={styles.bar}>
              <Text style={styles.title}>Title</Text>
            </View>
          </Animated.View>
        </View>
      );
    };

    ScrollableHeader.propTypes = {
      navigation: PropTypes.shape({
        navigate: PropTypes.func.isRequired,
      }).isRequired,
    };

    export default ScrollableHeader;

这篇关于有什么办法使本机ScrollView onScroll钩子产生动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆