如何在ScrollView中平滑动画marginTop过渡?

时间:2017-05-03 18:40:47

标签: react-native react-native-scrollview

对于我的项目,我希望实现一个ScrollView,它可以显示项目,就好像您正在浏览一盒名片一样。我将我当前的实现基于Albert Brand's article on Animated ScrollViews(在尝试了许多其他方法之后)。

然而,现在整个事情变得非常紧张。任何人都可以建议我如何平滑当前的实现?或者,是否有人提示如何以不同的方式获得此行为?任何解决方案都应该适用于iOS和Android。

这个gif显示了我当前的实现,包括抖动问题。它还应该清楚地说明我之后的行为:  screencapture of the ScrollView in iOS simulator

这是我目前的实施:

import React from 'react'
import {
  Animated,
  Dimensions,
  ScrollView,
  StyleSheet,
  Text,
  View,
  StatusBar,
} from 'react-native'

const SCREEN_HEIGHT = Dimensions.get('window').height

const yOffset = new Animated.Value(0)

const onScroll = Animated.event(
  [{ nativeEvent: { contentOffset: { y: yOffset } } }],
)

function CardView(props: { children?: ReactElement<*> }) {
  return (
    <Animated.ScrollView
      scrollEventThrottle={16}
      onScroll={onScroll}
      pagingEnabled
    >
      {props.children}
    </Animated.ScrollView>
  )
}

function Page(props: { children?: ReactElement<*>, index: 1 }) {
  return (
    <Animated.View style={[style.scrollPage]}>
      {props.children}
    </Animated.View>
  )
}

function Card(props: { text: string, index: number }) {
  return (
    <Animated.View style={[style.card, marginTransform(props.index)]}>
      <Text>
        {props.text}
      </Text>
    </Animated.View>
  )
}

function marginTransform(index: number) {
  return {
    marginTop: yOffset.interpolate({
      inputRange: [
        (index - 1) * SCREEN_HEIGHT,
        index * SCREEN_HEIGHT,
        (index + 1) * SCREEN_HEIGHT,
        (index + 2) * SCREEN_HEIGHT,
        (index + 3) * SCREEN_HEIGHT,
      ],
      outputRange: [
        -40,
        80,
        SCREEN_HEIGHT + 40,
        2 * SCREEN_HEIGHT + 20,
        3 * SCREEN_HEIGHT,
      ],
      extrapolate: 'clamp',
    }),
  }
}

export default function App() {
  return (
    <CardView>
      {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) => {
        return(
          <Page key={i}>
            <Card text={`Card ${i}`} index={i}>
            </Card>
          </Page>
        )
      })}
    </CardView>
  )
}

const style = StyleSheet.create({
  scrollPage: {
    height: SCREEN_HEIGHT,
    backgroundColor: 'transparent',
  },
  card: {
    height: SCREEN_HEIGHT,
    alignItems: 'center',
    borderRadius: 4,
    borderWidth: 1,
    backgroundColor: '#F5FCFF',
  }
})

3 个答案:

答案 0 :(得分:0)

确保已禁用Debug JS Remote。您还应该删除类中的所有console.log()(例如,如果出于调试原因记录yOffset)。这应该可以加快速度。

答案 1 :(得分:0)

我发现简短的回答:如果在滚动时弄乱它的高度,ScrollViews将永远不会动画。在旁注中,我确实发现当我设置scrollEventThrottle={1}

时,性能会大幅提升

我最终实现的解决方案是制作我自己的组件;在元素列表上呈现ScrollView。我将这些元素的动画高度值连接到ScrollView的滚动y偏移量。

如果有人遇到相同的用例实施问题,请随时使用我的作品:https://github.com/isilher/react-native-card-scroll

答案 2 :(得分:-1)

嘿试试这个main会帮助你摆脱困境

useNativeDriver: true