skip to Main Content

Basically I am trying to build a scrollable view in which i have a draggable container. When i drag the container to the bottom or top of the page i want the scroll view to start scrolling down or up. When i stop dragging or drag away from the boundary, then the scroll animation should stop.

I have tried to create a simplified version of this, via using two buttons one to start autoscrolling and one to stop it. The auto scrolling start, but i can’t cancel the animation. Moreover if i place an if statement in the animation, and make it false, the scrollView auto scrolls to the end imediatly. My guess is cancelAnimation stops the animation of scrolling but doesnt cause the scrollTo to stop.

I am using the latest version of reanimated and expo

I am new to react native and reanimated, but come from web development, where i have accomplished this before in a event calendar app.

Any help would be appreciated 🙂

import React from 'react';
import { Button, StyleSheet, View } from 'react-native';
import Animated, { scrollTo, useSharedValue, useAnimatedScrollHandler, cancelAnimation, useAnimatedReaction, useAnimatedRef } from 'react-native-reanimated';

const AnimatedScrollView = () => {
    const scrollY = useSharedValue(0);
    const scrollRef = useAnimatedRef();

    const scrollHandler = useAnimatedScrollHandler({
        onScroll: ({ contentOffset: { y } }) => {
          scrollY.value = y;
        },
      });

    const startScroll = () => {
        scrollY.value += 50;
        scrollTo(scrollRef, 0, scrollY.value, false);
    };

    const stopScroll = () => {
        cancelAnimation(scrollY);
    };

    useAnimatedReaction(
        () => scrollY.value,
        (scrollPosition) => {
            console.log(scrollPosition);
            scrollTo(scrollRef, 0, 1000, true);
        }
    );

    return (
        <>
            <Button title="Start Scrolling" onPress={startScroll} />
            <Button title="Stop Scrolling" onPress={stopScroll} />
            <Animated.ScrollView
                onScroll={scrollHandler}
                scrollEventThrottle={16}
                ref={scrollRef}
            >
                <View style={[styles.container, { backgroundColor: 'pink', }]}>

                </View>
                <View style={[styles.container, { backgroundColor: 'blue', }]}>

                </View>
                <View style={[styles.container, { backgroundColor: 'red', }]}>

                </View>
                <View style={[styles.container, { backgroundColor: 'pink', }]}>

                </View>
                <View style={[styles.container, { backgroundColor: 'blue', }]}>

                </View>
                <View style={[styles.container, { backgroundColor: 'red', }]}>

                </View>
            </Animated.ScrollView>
        </>
    );
};

export default AnimatedScrollView;


const styles = StyleSheet.create({
    container: {
        height: 300,
        width: '100%',
        backgroundColor: 'pink',
    }
})

2

Answers


  1. Chosen as BEST ANSWER

    Okay so the solution to this is to instead use

        const animatedProps = useAnimatedProps<any>(() => {
            return {
                contentOffset: {
                    x: 0,
                    y: scrollY.value,
                },
            };
        });
    

    and then just change the scrollY.value to scroll to a certain position instead of using the scrollTo built in function

    If anyone sees this quesitons and has issues similar, I built the calendar and think i have a pretty good understanding of reanimated 3 and React native now :)


  2. how did you adapt it to work with the draggable item?
    I tried implementing this, but I am not getting a smooth transition. any idea?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search