Android 在React Native中调用scroll上的函数一次
我正在构建一个应用程序,其中我有一个名为Android 在React Native中调用scroll上的函数一次,android,ios,animation,react-native,scrollview,Android,Ios,Animation,React Native,Scrollview,我正在构建一个应用程序,其中我有一个名为的可实现标题,它有一个propisCollaped(值可以是true或false),用于打开和关闭容器,还有一个(下面的屏幕截图,很抱歉没有英文文本)。 应用程序的屏幕截图: 我想在开始滚动时折叠,因此我将isCollaped的值设置为true,它可以工作,但因为每200毫秒调用onScroll,并且在松开手指后滚动动画不会停止,当我再次按下按钮试图打开时,如果滚动动画仍然处于活动状态,我会得到一个非常糟糕的动画,再次折叠 这部分代码在按下搜索栏时调整
的可实现标题,它有一个propisCollaped
(值可以是true或false),用于打开和关闭容器,还有一个
(下面的屏幕截图,很抱歉没有英文文本)。
应用程序的屏幕截图:
我想在开始滚动
时折叠
,因此我将isCollaped
的值设置为true,它可以工作,但因为
每200毫秒调用onScroll
,并且在松开手指后滚动动画不会停止,当我再次按下按钮试图打开
时,如果滚动动画仍然处于活动状态,我会得到一个非常糟糕的动画,再次折叠
这部分代码在按下搜索栏时调整其大小:
collapseSearchBar = () => {
this.setState({
searchBarCollapsed: !this.state.searchBarCollapsed,
});
};
这是
:
这是
的代码:
{
返回此._renderRow(rowData,this.props.navigation);
}}
onScroll={()=>{
如果(!this.state.searchBar崩溃){
这是我的国家({
搜索引擎:对
});
}
}}
/>
我的问题是:在动画处于活动状态时,当用户滑动
时,而不是在所有时间(每200ms,动画开始后大约3秒)时,我如何才能调用
一次滚动
事件。您可以使用道具设置滚动
事件触发的频率
scrollEventThrottle
<ListView
ref='mainScrollView'
dataSource={this.state.dataSource}
renderRow={(rowData) => {
return this._renderRow(rowData, this.props.navigation);
}}
onScroll={() => {
if (!this.state.searchBarCollapsed) {
this.setState({
searchBarCollapsed: true,
isAnimating: true
});
}
}}
/>
这控制滚动时触发滚动事件的频率
(以毫秒为单位的时间间隔)。较低的数字会产生更好的精度
跟踪滚动位置但可能导致滚动的代码
由于发送的信息量过大而导致的性能问题
桥。您不会注意到设置的值之间的差异
在1-16之间,因为JS运行循环与屏幕刷新率同步。
如果不需要精确的滚动位置跟踪,请设置此值
更高,以限制跨桥发送的信息。这个
默认值为零,这将导致发送滚动事件
每次仅滚动视图一次
但我不认为这能解决你的问题。您可以设置第二个状态值(类似于isAnimating
)并在设置标题动画之前进行检查。动画结束后,可以将其设置回false
示例
<ListView
ref='mainScrollView'
dataSource={this.state.dataSource}
renderRow={(rowData) => {
return this._renderRow(rowData, this.props.navigation);
}}
onScroll={() => {
if (!this.state.searchBarCollapsed) {
this.setState({
searchBarCollapsed: true,
isAnimating: true
});
}
}}
/>
在我的例子中,我必须在向上滚动一次和向下滚动一次时设置视图的动画。基本上,它喜欢向下滚动时显示视图,向上滚动时隐藏视图。由于该函数在滚动时被多次调用,因此在视图中会产生闪烁效果。因此,我创建了一个状态“向下滚动”) 在我的情况下,最初scrollDown将为true,表示用户将首先向下滚动。动画会执行,因为它是真的,它也会将自身更新为假,所以下次动画不会执行。当然scrollDown将给出true,但这些代码不会执行,因为它们是用于向上滚动的。所以,一旦用户向上滚动,则向下滚动值将更新,并遵循相同的逻辑
const _toogleNavigationBtn = (event) => {
const currentOffset = event.nativeEvent.contentOffset.y;
if(scrollDown)
if(currentOffset > offset && offset > 0 ){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 50,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
const contentSize = parseInt(event.nativeEvent.contentSize.height)
const scrolledSize = parseInt(currentOffset + event.nativeEvent.layoutMeasurement.height)
if(!scrollDown)
if(offset === 0 || currentOffset < offset || contentSize == scrolledSize){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 0,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
setOffset(prevState => currentOffset)
}
const\u toogleNavigationBtn=(事件)=>{
const currentOffset=event.nativeEvent.contentOffset.y;
如果(向下滚动)
如果(当前偏移>偏移和偏移>0){
setScrollDown(prevState=>!prevState)
动画。计时(导航BTNY{
toValue:50,
持续时间:700,
放松:放松.out(放松.exp)
}).start();
}
const contentSize=parseInt(event.nativeEvent.contentSize.height)
const scrolledSize=parseInt(currentOffset+event.nativeEvent.layoutMeasurement.height)
如果(!向下滚动)
if(offset==0 | | currentOffset!prevState)
动画。计时(导航BTNY{
toValue:0,
持续时间:700,
放松:放松.out(放松.exp)
}).start();
}
setOffset(prevState=>currentOffset)
}
正如您所说,scrollEventThrottle对我不起作用,因此我也尝试了第二种方法,但似乎不起作用。它只允许我折叠
一次,然后什么也不做,我想这是因为没有一行代码,其中isAnimating
值设置为false
。也许您可以建议对代码进行一些更改,以便动画始终工作。@MishoTektumanidze我不能提出任何其他建议,因为我不知道如何为组件设置动画。我的只是一个关于如何实现期望行为的建议。您需要在代码中以某种方式实现它。
collapseSearchBar = () => {
this.interval = setInterval(() => {
if (this.state.isAnimating === false) {
this.setState({
searchBarCollapsed: !this.state.searchBarCollapsed,
isAnimating: true
});
clearInterval(this.interval);
this.interval = null;
}
}, 100)
};
const [scrollDown, setScrollDown] = useState(true)
const _toogleNavigationBtn = (event) => {
const currentOffset = event.nativeEvent.contentOffset.y;
if(scrollDown)
if(currentOffset > offset && offset > 0 ){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 50,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
const contentSize = parseInt(event.nativeEvent.contentSize.height)
const scrolledSize = parseInt(currentOffset + event.nativeEvent.layoutMeasurement.height)
if(!scrollDown)
if(offset === 0 || currentOffset < offset || contentSize == scrolledSize){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 0,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
setOffset(prevState => currentOffset)
}