有了这个参考 Problems with parallax header in react native
找到的唯一解决方案只是隐藏刷新组件的黑客,因为contentContainerStyle不与refreshcomponent交互。
因此,唯一的解决方案是移动scrollview组件,但在滚动时移动它是非常滞后和惊人的。 有解决方案吗 这是非常常见的情况,我的意思是.Facebook app和Twitter app都有这种类型的主屏幕!
示例动画是: animated header from play store app home
添加零食: snack esample of header animation
如你所见,在Android上,上下滚动开始交错,因为2动画(容器和滚动)是并发的:它们不混合,每个都试图动画..疯狂。
答案 0 :(得分:2)
更新3 : snack solution good for android and ios
更新:complete snack with gif like animation
我找到了第一个部分解决方案的解决方法(带有transform translate的绝对头文件和带有paddingTop的contentContainerStyle)
问题仅出在刷新组件上,那该怎么办?
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
<AnimatedFlatList
data={data}
renderItem={item => this._renderRow(item.item, item.index)}
scrollEventThrottle={16}
onScroll={Animated.event([
{ nativeEvent: { contentOffset: { y: this.state.scrollAnim } }, },
], { useNativeDriver: true })}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={() => {
this.setState({ refreshing: true });
setTimeout(() => this.setState({ refreshing: false }), 1000);
}}
// Android offset for RefreshControl
progressViewOffset={NAVBAR_HEIGHT}
/>
}
// iOS offset for RefreshControl
contentInset={{
top: NAVBAR_HEIGHT,
}}
contentOffset={{
y: -NAVBAR_HEIGHT,
}}
/>
这将在refreshController上应用偏移样式,使其与内容对齐。
UPDATE2: 在ios上有一些问题。
UPDATE3: 也固定在ios上。
答案 1 :(得分:1)
您可以尝试使用react-spring library,因为它支持Parallax效果以反应原生。
更新:您的示例
中的工作解决方案import React, { Component } from 'react';
import { Animated, Image, Platform, StyleSheet, View, Text, FlatList } from 'react-native';
const data = [
{
key: 'key',
name: 'name',
image: 'imageUrl',
},
];
const NAVBAR_HEIGHT = 90;
const STATUS_BAR_HEIGHT = Platform.select({ ios: 20, android: 24 });
const styles = StyleSheet.create({
fill: {
flex: 1,
},
navbar: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
alignItems: 'center',
backgroundColor: 'white',
borderBottomColor: '#dedede',
borderBottomWidth: 1,
height: NAVBAR_HEIGHT,
justifyContent: 'center',
paddingTop: STATUS_BAR_HEIGHT,
},
contentContainer: {
flex: 1,
},
title: {
color: '#333333',
},
row: {
height: 300,
width: null,
marginBottom: 1,
padding: 16,
backgroundColor: 'transparent',
},
rowText: {
color: 'white',
fontSize: 18,
},
});
export default class App extends Component {
constructor(props) {
super(props);
const scrollAnim = new Animated.Value(0);
this._clampedScrollValue = 0;
this._offsetValue = 0;
this._scrollValue = 0;
this.state = {
scrollAnim,
};
}
_renderRow(rowData, rowId) {
return (
<View style={{ flex: 1 }}>
<Image key={rowId} style={styles.row} source={{ uri: rowData.image }} resizeMode="cover" />
<Text style={styles.rowText}>{rowData.title}</Text>
</View>
);
}
render() {
const { scrollAnim } = this.state;
const navbarTranslate = scrollAnim.interpolate({
inputRange: [0, NAVBAR_HEIGHT - STATUS_BAR_HEIGHT],
outputRange: [0, -(NAVBAR_HEIGHT - STATUS_BAR_HEIGHT)],
extrapolate: 'clamp',
});
const navbarOpacity = scrollAnim.interpolate({
inputRange: [0, NAVBAR_HEIGHT - STATUS_BAR_HEIGHT],
outputRange: [1, 0],
extrapolate: 'clamp',
});
return (
<View style={styles.fill}>
<View style={styles.contentContainer}>
<FlatList
data={data}
renderItem={item => this._renderRow(item.item, item.index)}
scrollEventThrottle={16}
onScroll={Animated.event([
{ nativeEvent: { contentOffset: { y: this.state.scrollAnim } } },
])}
/>
</View>
<Animated.View style={[styles.navbar, { transform: [{ translateY: navbarTranslate }] }]}>
<Animated.Text style={[styles.title, { opacity: navbarOpacity }]}>PLACES</Animated.Text>
</Animated.View>
</View>
);
}
}
答案 2 :(得分:0)
万一其他人落在这个线程上,我开发了一个新程序包, react-native-animated-screen ,它完全满足您的需求
签出