【问题标题】:How to use Animated.diffClamp in react native如何在本机反应中使用 Animated.diffClamp
【发布时间】:2017-01-27 19:52:31
【问题描述】:

任何代码示例如何实现 Animated.diffClamp?

我正在尝试创建一个类似于 google play 应用程序中的标题滚动动画。当您开始向下滚动时,我已经隐藏了标题,但问题是我想在您开始向上滚动时再次显示标题,它仅在您到达视图顶部时显示。

class Services extends Component {
  constructor(props){
  super(props);
  this.state = {
    scrollY : new Animated.Value(0),
  }
}

renderScrollViewContent(){
  return (
    <View style={styles.scrollViewContent}>
    </View>
  )
}

render() {
  const headerHeight = this.state.scrollY.interpolate({
    inputRange: [0, 60],
    outputRange: [0, -60],
    extrapolate: 'clamp'
  });

  return (
    <View style={styles.container}>
      <ScrollView style={styles.container}
        scrollEventThrottle={16}
        onScroll={Animated.event(
          [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
        )}
      >
        {this.renderScrollViewContent()}
      </ScrollView>
      <Animated.View style={[styles.header, {top: headerHeight}]}>
        <View style={styles.bar}>
          <Text style={styles.title}>Title</Text>
        </View>
      </Animated.View>
    </View>
  );
 }
}

【问题讨论】:

    标签: android animation react-native


    【解决方案1】:

    我们正是为这个用例添加了这个。这是文档页面https://reactnative.dev/docs/animated#diffclamp

    我还建议将它与翻译转换一起使用(性能更好,并且可以与本机驱动程序一起使用)。这是您使用它的示例渲染:

    const headerTranslate = Animated.diffClamp(this.state.scrollY, 0, 60)
      .interpolate({
        inputRange: [0, 1],
        outputRange: [0, -1],
      });
     
    return (
     <View style={styles.container}>
       <ScrollView style={styles.container}
         scrollEventThrottle={16}
         onScroll={Animated.event(
           [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
         )}
       >
         {this.renderScrollViewContent()}
       </ScrollView>
       <Animated.View style={[styles.header, {transform: [{translateY: headerTranslate}]}]}>
         <View style={styles.bar}>
           <Text style={styles.title}>Title</Text>
         </View>
       </Animated.View>
     </View>
    );
    

    它的工作原理是我们将滚动位置传递给 diffClamp,因此在我们使用 interpolate 使值变为负值(我们希望它向上平移)之后,它被限制在 0 到 60 之间。

    【讨论】:

    • 我正在尝试使用本机驱动程序通过 Animated.event 实现 diffClamp。但我似乎对动画值的结果几乎没有控制权。我想让与 iOS Facebook 应用程序相同的标题滚动,但我遇到了几个问题。当位于视图顶部或过度滚动视图时,我似乎无法阻止标题隐藏。此外,如果用户在导航栏位于幻灯片动画中间时停止滚动,它应该动画到完全隐藏/可见。当我无法从事件中读取当前滚动值时,我看不出如何实现这些。
    • 我前几天实际实现了,我整理一下,贴在这里。
    • 抱歉耽搁了,我用一个例子做了一个回购github.com/janicduplessis/collapsible-navbar
    • 知道如何在使用 diffClamp 时防止标题反弹吗?例如,当您上下滚动时,一切都很好。但是,如果您拉动刷新怎么办。列表视图的弹性使标题隐藏。
    • @tnaught 我们能够通过在列表视图上添加bounces: false 来解决我们的具体问题。这可能是也可能不是您的问题的解决方案,但它当时适合我们。
    【解决方案2】:

    这是一个从顶部出现标题的示例,仅在用户滚动到最小 Y 位置后,并通过夹紧解决过度滚动/弹跳问题。

    const minScroll = 100;
    
    const clampedScrollY = scrollY.interpolate({
      inputRange: [minScroll, minScroll + 1],
      outputRange: [0, 1],
      extrapolateLeft: 'clamp',
    });
    
    const minusScrollY = Animated.multiply(clampedScrollY, -1);
    
    const translateY = Animated.diffClamp(
      minusScrollY,
      -AnimatedHeaderHeight,
      0,
    );
    
    const opacity = translateY.interpolate({
      inputRange: [-AnimatedHeaderHeight, 0],
      outputRange: [0.4, 1],
      extrapolate: 'clamp',
    });
    

    更多详情:https://stackoverflow.com/a/51638296/82609

    【讨论】:

      【解决方案3】:

      V0.65react-native 开始,您可以使用stickyHeaderHiddenOnScroll 道具。

      这里是这样做的文档:https://reactnative.dev/docs/0.65/scrollview#stickyheaderhiddenonscroll

      提醒一下,Expo SDK43 仅支持 react-native: 0.64.3

      【讨论】:

        猜你喜欢
        • 2021-12-29
        • 1970-01-01
        • 2021-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-15
        相关资源
        最近更新 更多