我想将类的基础组件转换为用于动画的功能基础组件。 https://snack.expo.io/@wyrustaaruz/animation-test-class-base
您可以使用小吃链接来更改代码。 您也可以在下面的行中查看代码。 这段代码在基于类的基础组件上运行良好。
我尝试了useRef,useState,但无法解决此问题。
这是我的功能基础链接:
https://snack.expo.io/@wyrustaaruz/animated-with-functional-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,
},
});
答案 0 :(得分:1)
您在这里;)
请记住,您必须使用Animated.ScrollView
才能使事件正常运行。
这是更新的小吃链接: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;