React Native:Animate缩小标题的标题

时间:2017-05-19 13:22:55

标签: javascript react-native

目标

我尝试创建一个带有动画缩小标题的视图,其中tabview包含带滚动内容的标签。 见图。

设置

我正在使用带有TabNavigator的react-navigation。标题是具有固定高度的组件,当前位于TabNavigator上方。标题一直固定在标签上方占用宝贵的空间。

尝试过的方法

  • 我已尝试过Janic Duplessis Blog Post但由于标签我无法使用它。

  • 我也尝试用两个ScrollView / FlatList实现它:一个环绕整个视图,一个包裹内容,但我无法做出反应本地传播滚动边缘。

所需效果与Google Play商店相同。

Mobile Screenshot Google play

2 个答案:

答案 0 :(得分:14)

我设法通过Animated.diffClamp实现了这一点 - 您可以查看代码here。我已经写了一篇文章,更详细地解释了代码here

*我在UI组件中使用原生基础包(以简化UI代码),但无论是否有动画插值/定义都是相同的。

Demo

答案 1 :(得分:2)

您可以通过使用RN-Animated组件自行控制动画滚动操作来实现此目的。这不是你要求的,但它可以轻松地播放以获得正确的结果,你真的只需要使用任何列表视图的renderScrollComponent方法捕获同样的东西......所以..这是一些代码:

守则

constructor(props) {
    super(props);

    this.headerHeight = 150;

    this.state = {
        scrollY: new Animated.Value(0),
    };
}

render() {
    return (
        <View style={[
                styles.container,
                {
                    width: this.props.display.width,
                    height: this.props.display.height,
                }
            ]}>

            { this.renderScrollView() }
            { this.renderListHeader() }

        </View>
    );
}


renderListHeader() {
    return (
        <Animated.View
            style={[
                styles.headerContainer,
                {
                    width: this.props.display.width,
                    height: this.state.scrollY.interpolate({
                        inputRange: [0, this.headerHeight],
                        outputRange: [this.headerHeight, this.headerHeight / 2],
                        extrapolate: 'clamp',
                    }),
                }
            ]}>

            <Text style={[bodyFontStyle, styles.testingText]}>
                I am a test! 
            </Text>
        </Animated.View>
    );
}


renderScrollView() {
    return (
        <Animated.ScrollView
            bounces={false}
            scrollEventThrottle={1}
            showsVerticalScrollIndicator={false}
            showsHorizontalScrollIndicator={false}
            onScroll={Animated.event( [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }] )}>

            <Animated.View
                style={[
                    styles.innerScrollContainer,
                    {
                        height: 800,
                        width: this.props.display.width,
                        marginTop: this.headerHeight,
                    }
                ]}>

                <Text style={[bodyFontStyle, styles.innerContainerText]}>
                    Look ma! No Hands!
                </Text>
            </Animated.View>
        </Animated.ScrollView>
    );
}


const styles = StyleSheet.create({
    container: {
        position: 'relative',
        backgroundColor: 'transparent',
    },
    headerContainer: {
        position: 'absolute',
        top: 0, left: 0,
        overflow: 'hidden',
        backgroundColor: 'green',
   },
   innerScrollContainer: {
        position: 'relative',
        backgroundColor: 'white',
   },
   innerContainerText: { color: 'black' },
   testingText: { color: 'black' },
});

我确信你已经明白了这段代码正在尝试做什么......但是只是因为故障会发生故障。

代码细分

我使用this.props.display.width / height支持向下发送当前设备屏幕宽度/高度的系统级别宽度/高度,但如果您更喜欢使用flex而不是。

您不一定需要硬编码或静态标头大小,只需要在类代码中使用它的中心位置(即类级别或JS模块级别)。

最后,仅仅因为我将滚动数据插入到框的高度,并不意味着你必须这样做。在示例中,您显示它看起来更像是您想要向上翻译框而不是缩小它的高度。