Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在React Native中调用scroll上的函数一次_Android_Ios_Animation_React Native_Scrollview - Fatal编程技术网

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,并且在松开手指后滚动动画不会停止,当我再次按下按钮试图打开时,如果滚动动画仍然处于活动状态,我会得到一个非常糟糕的动画,再次折叠 这部分代码在按下搜索栏时调整

我正在构建一个应用程序,其中我有一个名为
的可实现标题,它有一个prop
isCollaped
(值可以是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)
}