react-native:根据滚动位置更改视图
react-native:根据滚动位置更改视图
我正在使用Animation.view
来改变header
的height
和background
。\n我设置了height
和background
的设置,如下所示:\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我的问题是,有没有办法像height
和backgroundcolor
一样改变view
?\n例如,假设我有两个view
:\n
//view1//view2 View1 View2
\n我希望view1
默认显示,并在滚动到屏幕顶部时显示view2
。将View
放在outputRange
中是否可以实现这一点?
问题的出现原因是:用户希望在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)
感谢回复。我知道可以动态改变颜色或高度。但这不是我想要实现的。
问题出现的原因是希望根据滚动位置改变视图的外观,即根据滚动的偏移量来改变不同视图的透明度。
解决方法是使用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方法来计算两个视图的透明度,根据滚动位置的不同来改变它们的外观。
在React Native中,如果你想要在滚动时动态改变视图,可能没有直接的方法。然而,你可以使用opacity
、position: absolute
和interpolate()
的组合来实现一个小技巧。下面是一个可以直接复制和粘贴进行测试的最小示例:
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
中放置button
和touchableOpacity
。但是如果我将button
或touchableOpacity
放在你的代码的Animated.View
中,onPress
就不起作用了。
这是因为蓝色视图实际上覆盖了红色视图,你是否在红色视图上放置了touchableOpacity
?
实际上,我计划在两个视图中都放置touchableOpacity
。在两个视图中都放置touchableOpacity
是可能的吗?
我们可以在聊天中继续讨论这个问题。