修改於第三方插件https://github.com/lelandrichardson/react-native-parallax-view node
官方的原效果:react
實際我所須要的效果:git
如上圖所示,在開發過程當中咱們遇到了如下問題:github
'use strict'; var React = require('react'); var ReactNative = require('react-native'); var { Dimensions, StyleSheet, View, ScrollView, Animated, } = ReactNative; /** * BlurView temporarily removed until semver stuff is set up properly */ //var BlurView /* = require('react-native-blur').BlurView */; var ScrollableMixin = require('react-native-scrollable-mixin'); var screen = Dimensions.get('window'); import PropTypes from 'prop-types'; var ScrollViewPropTypes = ScrollView.propTypes; var createReactClass=require("create-react-class"); var ParallaxView = createReactClass({ mixins: [ScrollableMixin], propTypes: { ...ScrollViewPropTypes, windowHeight: PropTypes.number, backgroundSource:PropTypes.oneOfType([ PropTypes.shape({ uri: PropTypes.string, }), // Opaque type returned by require('./image.jpg') PropTypes.number, ]), header:PropTypes.node, blur: PropTypes.string, contentInset:PropTypes.object, }, getDefaultProps: function () { return { windowHeight: 300, contentInset: { top: screen.scale } }; }, getInitialState: function () { return { scrollY: new Animated.Value(0) }; }, /** * IMPORTANT: You must return the scroll responder of the underlying * scrollable component from getScrollResponder() when using ScrollableMixin. */ getScrollResponder() { return this._scrollView.getScrollResponder(); }, setNativeProps(props) { this._scrollView.setNativeProps(props); }, renderBackground: function () { var { windowHeight, backgroundSource, blur } = this.props; var { scrollY } = this.state; if (!windowHeight || !backgroundSource) { return null; } return ( <Animated.Image style={[styles.background, { height: windowHeight, transform: [{ translateY: scrollY.interpolate({ inputRange: [ -windowHeight, 0, windowHeight], //本來是-windowHeight/3 outputRange: [windowHeight/2, 0, -windowHeight] }) },{ scale: scrollY.interpolate({ inputRange: [ -windowHeight, 0, windowHeight], outputRange: [2, 1, 1] }) }] }]} source={backgroundSource}> {/* !!blur && (BlurView || (BlurView = require('react-native-blur').BlurView)) && <BlurView blurType={blur} style={styles.blur} /> */} </Animated.Image> ); }, renderHeader: function () { var { windowHeight, backgroundSource } = this.props; var { scrollY } = this.state; if (!windowHeight || !backgroundSource) { return null; } return ( <Animated.View style={{ position: 'relative', height: windowHeight, // opacity: scrollY.interpolate({ // inputRange: [-windowHeight, 0, windowHeight / 1.2], // outputRange: [1, 1, 0] // }), }}> {this.props.header} </Animated.View> ); }, render: function () { var { style, ...props } = this.props; return ( <View style={[styles.container, style]}> {/*{this.renderBackground()}之前的*/} {this.props.header} {/*修改後的*/} <ScrollView ref={component => { this._scrollView = component; }} {...props} style={styles.scrollView} onScroll={ Animated.event([{ nativeEvent: { contentOffset: { y: this.state.scrollY }}}]) } scrollEventThrottle={16}> {this.renderHeader()} {/*<View style={[styles.content, props.scrollableViewStyle]}>*/} {this.props.children} {/*</View>*/} </ScrollView> </View> ); } }); var styles = StyleSheet.create({ container: { flex: 1, borderColor: 'transparent', }, scrollView: { backgroundColor: 'transparent', }, background: { position: 'absolute', backgroundColor: '#2e2f31', width: screen.width, resizeMode: 'cover' }, blur: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, backgroundColor: 'transparent', }, content: { shadowColor: '#222', shadowOpacity: 0.3, shadowRadius: 2, backgroundColor: '#fff', flex: 1, flexDirection: 'column' } }); export default ParallaxView;