Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

How to add scrollview to card in react native

$
0
0

I am trying to add a Scrollview to my card in react native. However my card is animated and if I try to scroll I think it assumes it for swiping up instead. Alongside this the way my card is set out currently has turned the card into one long card rather than a set size card that can be scrolled.

Here is what my card looks like:enter image description here

Although it doesnt show it well, the card has just elongated rather than kept the same size and added a scrolling option.The code for my card is:

const Card = ({              name,              source,              isFirst,              swipe,              tiltSign,              ...rest          }: props) => {const rotate = Animated.multiply(swipe.x, tiltSign).interpolate({    inputRange: [-ACTION_OFFSET, 0, ACTION_OFFSET],    outputRange: ['8deg', '0deg', '-8deg'],});const likeOpacity = swipe.x.interpolate({    inputRange: [25, ACTION_OFFSET],    outputRange: [0, 1],    extrapolate: 'clamp',});const nopeOpacity = swipe.x.interpolate({    inputRange: [-ACTION_OFFSET, -25],    outputRange: [1, 0],    extrapolate: 'clamp',});const animatedCardStyle = {    transform: [...swipe.getTranslateTransform(), {rotate}],};const renderChoice = useCallback(() => {    return (<><Animated.View                style={[                    styles.choiceContainer,                    styles.likeContainer,                    {opacity: likeOpacity},                ]}><Choice type="like"/></Animated.View><Animated.View                style={[                    styles.choiceContainer,                    styles.nopeContainer,                    {opacity: nopeOpacity},                ]}><Choice type="nope"/></Animated.View></>    );}, [likeOpacity, nopeOpacity]);return (<Animated.ScrollView        style={[styles.container, isFirst && animatedCardStyle]}        {...rest}><Image source={source} style={styles.image}/><Text style={styles.name}>{name}</Text><Text>Hello</Text><Image source={source} style={styles.image}/><Image source={source} style={styles.image}/><Image source={source} style={styles.image}/><LinearGradient            colors={['transparent', 'rgba(0,0,0,0.9)']}            style={styles.gradient}        />        {isFirst && renderChoice()}</Animated.ScrollView>);

I feel the styling of it may also help:

container: {    position: 'absolute',    top: 45,},image: {    width: CARD.WIDTH,    height: CARD.HEIGHT,    borderRadius: CARD.BORDER_RADIUS,},gradient: {    position: 'absolute',    bottom: 0,    left: 0,    right: 0,    height: 160,    borderRadius: CARD.BORDER_RADIUS,},name: {    position: 'absolute',    bottom: 22,    left: 22,    fontSize: 36,    fontWeight: 'bold',    color: '#fff',},choiceContainer: {    position: 'absolute',    top: 100,},likeContainer: {    left: 45,    transform: [{ rotate: '-30deg' }],},nopeContainer: {    right: 45,    transform: [{ rotate: '30deg' }],},

Here is also my swiping screen which the card is used in:

    import React, { useCallback, useEffect, useRef, useState } from 'react';import { Animated, PanResponder, View } from 'react-native';import Card from '../card/Card';import { ACTION_OFFSET, CARD } from '../../utils/constants';import { pets as petsArray } from './data';import {styles} from "./styles";const Swipe = () => {    const [pets, setPets] = useState(petsArray);    const swipe = useRef(new Animated.ValueXY()).current;    const tiltSign = useRef(new Animated.Value(1)).current;    useEffect(() => {        if (!pets.length) {            setPets(petsArray);        }    }, [pets.length]);    const panResponder = PanResponder.create({        onMoveShouldSetPanResponder: () => true,        onPanResponderMove: (_, { dx, dy, y0 }) => {            swipe.setValue({ x: dx, y: dy });            tiltSign.setValue(y0 > CARD.HEIGHT / 2 ? 1 : -1);        },        onPanResponderRelease: (_, { dx, dy }) => {            const direction = Math.sign(dx);            const isActionActive = Math.abs(dx) > ACTION_OFFSET;            if (isActionActive) {                Animated.timing(swipe, {                    duration: 200,                    toValue: {                        x: direction * CARD.OUT_OF_SCREEN,                        y: dy,                    },                    useNativeDriver: true,                }).start(removeTopCard);            } else {                Animated.spring(swipe, {                    toValue: {                        x: 0,                        y: 0,                    },                    useNativeDriver: true,                    friction: 5,                }).start();            }        },    });    const removeTopCard = useCallback(() => {        setPets((prevState) => prevState.slice(1));        swipe.setValue({ x: 0, y: 0 });    }, [swipe]);    const handleChoice = useCallback(        (direction) => {            Animated.timing(swipe.x, {                toValue: direction * CARD.OUT_OF_SCREEN,                duration: 400,                useNativeDriver: true,            }).start(removeTopCard);        },        [removeTopCard, swipe.x]    );    return (<View style={styles.container}>            {pets                .map(({ name, source }: any, index: number) => {                    const isFirst = index === 0;                    const dragHandlers = isFirst ? panResponder.panHandlers : {};                    return (<Card                            key={name}                            name={name}                            source={source}                            isFirst={isFirst}                            swipe={swipe}                            tiltSign={tiltSign}                            {...dragHandlers}                        />                    );                })                .reverse()}</View>    );};export default Swipe;

Any help as to how to just make the card scroll rather than what it is currently would be great! Thanks!


Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>