如何使用按钮事件滚动到下一页而不是 React Native 中的手势

How to scroll to the next page with a button event and not gesture in React Native

我想通过按钮事件滑动到下一页,而不是通过手势滚动。我的意思是,如果我按下按钮 Next,我希望页面滚动到下一页。

以下是我的两页代码:

export default () => {
    const [animation] = useState(new Animated.Value(0))

    const onPressHandler = () => {
      // this is where I expect the logic should be
    }

    return (
        <SafeAreaView style={styles.container}>
            <ScrollView
                pagingEnabled
                horizontal
                scrollEventThrottle={16}
                showsHorizontalScrollIndicator={false}
                onScroll={Animated.event([
                    {
                        nativeEvent: {
                            contentOffset: {
                                x: animation,
                            }
                        }
                    }
                ])}
            >
                <View style={{ width }}>
                    <Text>First Page</Text>
                    <Button title="Next" onPress={onPressHandler} />
                </View>
                <View style={{ width }}>
                </View>
            </ScrollView>
        </SafeAreaView>
    )
}

你可以直接使用ScrollView组件的scrollTo功能来滚动,这对维护基于索引的滚动很有帮助position.Use如下。

moveBody = index => {
      this.scrollRef.scrollTo({
        x: index * width,
        animation: false
      })
  }

<ScrollView pagingEnabled ref={node=>this.scrollRef=node}>
 ...
</ScrollView

记得获取正确的页面,确保视图覆盖整个屏幕width.So点击下一个按钮可以实现快照效果。

您可以将偏移量除以屏幕宽度得到索引。

index=e.nativeEvent.contentOffset.x/width

您可以从 ScrollView 滚动事件访问 e,例如 onScroll/onMomentumEnd....

您还可以通过将 false 分配给 scrollEnabled 属性来关闭滚动手势。

pagingEnabled 和 snapToInterval ScrollView 行为均由触摸和滑动事件激活。因此它们不会通过以编程方式滚动来触发。

您的 onPressHandler 必须根据您要滚动到的页面计算正确的 x 值,然后调用 scrollTo({x: targetPageX, y: 0, animated: true}).

我执行了 @tvanlaerhoven 的建议。

componentDidMount() {
    const _scrollView = createRef();
  }

  nextArrowHandler = page => {

    let gotoPage = 1;
    if (page == 2) {
      gotoPage = 2;
    } else if (page == 3) {
      gotoPage = 3;
    }

    this._scrollView.scrollTo({
      x: width * gotoPage,
      y: 0,
      animated: true
    });
  };
// ...

 <ScrollView
          ref={ref => (this._scrollView = ref)}
// ...
>
<IntroScreenComponent
    nextArrow={this.nextArrowHandler.bind(this, "1")}
// ...

/>
<IntroScreenComponent
    nextArrow={this.nextArrowHandler.bind(this, "2")}
// ...

/>

我在 ScrollView 中有 3 个 IntroScreenComponent 组件,在每个组件中我触发传递页面 numbernextArrowHandler 函数,然后我将其与 width 的屏幕。

谢谢 ;)

根据您接受的答案,我想将其转换为 hooks,这样新用户可以更轻松地使用 hooks 如何做到这一点:

首先,从 react 导入 useRef, 像这样声明你的常量:

const scrollviewRef = useRef()

创建函数:

const moveBody = index => {
      scrollviewRef.current.scrollTo({
        x: index * width,
        animation: false
      })
}

并将该变量设置为您的滚动视图参考

<ScrollView pagingEnabled ref={scrollviewRef}>
 ...
</ScrollView

你可以使用这个:-

**let idx = 1;
const scrollRef = React.useRef();
const onPressHandler = () => {
  scrollRef.current.scrollToIndex({index:idx,animated:true});
};**

return (
    <SafeAreaView style={styles.container}>
        <ScrollView
            **ref={scrollRef}**
            pagingEnabled
            horizontal
            scrollEventThrottle={16}
            showsHorizontalScrollIndicator={false}
            onScroll={Animated.event([
                {
                    nativeEvent: {
                        contentOffset: {
                            x: animation,
                        }
                    },
                    **{
                       useNativeDriver:false,
                       listener: event => {
                         const offsetX = event.nativeEvent.contentOffset.x;
                         console.log(offsetX);
                         idx = offsetX/screenWidth;
                         idx += 1;
                       }
                     }**
                }
            ])}
        >
            <View style={{ width }}>
                <Text>First Page</Text>
                <Button title="Next" onPress={onPressHandler} />
            </View>
            <View style={{ width }}>
            </View>
        </ScrollView>
    </SafeAreaView>
)