react-native:根据滚动位置更改视图

21 浏览
0 Comments

react-native:根据滚动位置更改视图

我正在使用Animation.view来改变headerheightbackground。\n我设置了heightbackground的设置,如下所示:\n

const HeaderHeight = this.state.scrollY.interpolate({
      inputRange:[0, Header_Max_Height - Header_Min_Height],
      outputRange:[Header_Max_Height, Header_Min_Height],
      extrapolate:'clamp'
    })
const AnimateHeaderBackgroundColor = this.state.scrollY.interpolate({
        inputRange: [ 0, ( Header_Max_Height - Header_Min_Height )  ],
        outputRange: [ '#009688', '#00BCD4' ],
        extrapolate: 'clamp'
    })

\n这是我的animated.view。\n


\n一切都运行得很好。\n我的问题是,有没有办法像heightbackgroundcolor一样改变view?\n例如,假设我有两个view:\n

//view1

 View1

//view2

  View2

\n我希望view1默认显示,并在滚动到屏幕顶部时显示view2。将View放在outputRange中是否可以实现这一点?

0
0 Comments

问题的出现原因是:用户希望在React Native中使用ScrollView时,能够根据滚动位置动态改变View的外观。

解决方法是:使用onScroll回调函数来获取ScrollView中屏幕的位置,并在用户滚动到顶部时动态改变高度和颜色。

具体实现代码如下:

import React, { Component } from 'react';
import { ScrollView } from 'react-native';
class MyScrollView extends Component {
  handleScroll = (event) => {
    console.log(event.nativeEvent.contentOffset.y);
    // 根据滚动位置进行相应操作,如改变高度和颜色
  }
  render() {
    return (
      
    );
  }
}
export default MyScrollView;

通过以上代码,我们可以在ScrollView组件中添加onScroll属性,并将其值设置为handleScroll方法。在handleScroll方法中,通过event.nativeEvent.contentOffset.y来获取滚动位置,并根据需要进行相应操作。

参考链接:[Get current scroll position of ScrollView in React Native](https://stackoverflow.com/questions/29503252)

感谢回复。我知道可以动态改变颜色或高度。但这不是我想要实现的。

0
0 Comments

问题出现的原因是希望根据滚动位置改变视图的外观,即根据滚动的偏移量来改变不同视图的透明度。

解决方法是使用react-native中的Animated库,通过创建一个名为scrollY的Animated.Value来跟踪滚动的偏移量。然后在滚动视图的onScroll事件中使用Animated.event将滚动的偏移量与scrollY关联起来。在滚动事件中,通过scrollY.interpolate方法来根据不同的输入范围和输出范围来计算透明度,从而实现根据滚动位置改变视图外观的效果。

具体实现代码如下:

import React, { Component } from 'react';
import { StyleSheet, Animated, View, ScrollView, SafeAreaView } from 'react-native';
export default class AnimationExample extends Component {
  constructor(props) {
    super(props)
    this.state = {
      scrollY: new Animated.Value(0)
    }
  }
  render() {
    const {scrollY} = this.state;
    return (
      
        
          
            
            
          
        
      
    )
  }
}
const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
  },
  box: {
    height: 1000,
    width: '100%',
    position: 'absolute'
  },
  origin: {
    backgroundColor: 'red',
    zIndex: 1
  },
  target: {
    backgroundColor: 'blue',
    zIndex: 2
  },
  animatedViewsPositioner: {
    position: 'relative',
    backgroundColor: 'pink',
    height: 10000
  },
})

以上代码中的scrollY是一个Animated.Value对象,它通过onScroll事件来更新滚动的偏移量。在render函数中,可以看到在滚动视图内部有两个Animated.View组件,它们分别代表不同的视图。通过scrollY.interpolate方法来计算两个视图的透明度,根据滚动位置的不同来改变它们的外观。

0
0 Comments

在React Native中,如果你想要在滚动时动态改变视图,可能没有直接的方法。然而,你可以使用opacityposition: absoluteinterpolate()的组合来实现一个小技巧。下面是一个可以直接复制和粘贴进行测试的最小示例:

import React, { Component } from 'react';
import { StyleSheet, Animated, View, ScrollView } from 'react-native';
class AnimationExample extends Component {
  constructor(props) {
    super(props)
    this.state = {
      showBlueView: false,
      animatedOpacityValue: new Animated.Value(0),
    }
  }
  handleScroll = (event) => {
    const { animatedOpacityValue, showBlueView } = this.state;
    const scrollPosition = event.nativeEvent.contentOffset.y;
    if (scrollPosition > 100 && !showBlueView) {
      Animated.timing(animatedOpacityValue, {
        toValue: 1,
      }).start(() => this.setState({ showBlueView: true }))
    }
    if (scrollPosition < 100 && showBlueView) {
      Animated.timing(animatedOpacityValue, {
        toValue: 0,
      }).start(() => this.setState({ showBlueView: false }))
    }
  }
  render() {
    const { animatedOpacityValue } = this.state;
    return (
      
        
        
          
          
        
      
    )
  }
}
const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
  },
  green: {
    height: 600,
    width: '100%',
    backgroundColor: 'green',
  },
  red: {
    height: 300,
    width: '100%',
    backgroundColor: 'red',
  },
  blue: {
    position: 'absolute',
    height: 300,
    width: '100%',
    backgroundColor: 'blue',
  },
  animatedViewsPositioner: {
    position: 'relative',
  },
})

在上面的示例中,我首先通过将handleScroll函数应用于scrollView来获取滚动位置。确保将scrollEventThrottle设置为16,以确保函数每秒触发一次,但要注意可能由此引起的性能问题(如果你关心的话,你可以查看这里了解更多信息)。

为了实现在用户滚动到特定位置时触发视图变化(实际上并不是这样,但看起来像),我使用一个view来包裹红色和蓝色视图,红色视图的默认opacity: 1,而蓝色视图的默认opacity: 0,并位于红色视图上方。

我通过使用interpolate()来动画化它们的opacity来隐藏红色视图和显示蓝色视图。在这个过程中,两个opacity值都由放在状态中的一个animatedOpacityValue控制。我添加了一个状态showBlueView,通过避免在滚动时不断设置状态来优化性能。

以上是一个更新,为两个视图添加了touchableOpacity,通过在不使用时隐藏蓝色视图来实现。首先,添加一个日志函数:

log = (stringToPrint) => () => {
  console.log(stringToPrint)
}

接下来,将scrollView更改如下,添加了两个touchableOpacity


  
  
    
      
    
    {showBlueView && (
      
        
      
    )}
  

注意,我添加了showBlueView &&来隐藏蓝色视图,当其opacity为0时,这样它就不会阻挡应用于红色视图的任何点击事件(尽管蓝色视图被隐藏了,但实际上它位于带有opacity: 0的红色视图上方)。

感谢提供答案。我正在尝试。我将TouchableOpacity放在Animated.View中,但不起作用。你知道如何处理Animated.View中的TouchableOpacity吗?

你的意思是不起作用是指什么?你想要实现什么效果?

抱歉如果我没有表达清楚。我喜欢你的想法,它很好用。但是我尝试在滑动的view中放置buttontouchableOpacity。但是如果我将buttontouchableOpacity放在你的代码的Animated.View中,onPress就不起作用了。

这是因为蓝色视图实际上覆盖了红色视图,你是否在红色视图上放置了touchableOpacity

实际上,我计划在两个视图中都放置touchableOpacity。在两个视图中都放置touchableOpacity是可能的吗?

我们可以在聊天中继续讨论这个问题。

0