Reputation: 1180
I'm creating an Onboarding screen. I don't want to add buttons to this onboarding screen, the only way to go to the next page is by swiping. Although I need to have a way to get when the user is at the last screen, and when he swipes right, I will be redirecting him to the login screen.
This is the last screen on the app:
When the user swipes right from this screen, I want to make a redirect, like a function or a onPress.
This is the onboarding code:
import React, { useState, useRef } from 'react';
import {
Container,
FlatListContainer
} from './styles';
import {
FlatList,
Animated,
TouchableOpacity
} from 'react-native'
import OnboardingData from '../../utils/onboarding';
import { OnboardingItem } from '../../components/OnboardingItem';
import { Paginator } from '../../components/Paginator';
export function Onboarding(){
const [currentIndex, setCurrentIndex] = useState(0);
const scrollX = useRef(new Animated.Value(0)).current;
const scrollY = useRef(new Animated.Value(0)).current;
const onboardingDataRef = useRef(null);
const viewableItemsChanged = useRef(({ viewableItems }: any) => {
setCurrentIndex(viewableItems[0].index);
}).current;
const viewConfig = useRef({ viewAreaCoveragePercentThreshold: 50 }).current;
return (
<Container>
<FlatListContainer>
<FlatList
data={OnboardingData}
renderItem={({ item }) => <OnboardingItem image={item.image} title={item.title} description={item.description}/>}
horizontal
showsHorizontalScrollIndicator={false}
pagingEnabled={true}
bounces={false}
keyExtractor={(item) => String(item.id)}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { x: scrollX } }}], {
useNativeDriver: false
})}
scrollEventThrottle={32}
onViewableItemsChanged={viewableItemsChanged}
viewabilityConfig={viewConfig}
ref={onboardingDataRef}
/>
</FlatListContainer>
<Paginator data={OnboardingData} scrollX={scrollX} scrollY={scrollY} currentIndex={currentIndex}/>
</Container>
);
}
Upvotes: 0
Views: 937
Reputation: 3540
I thought about it, and the old method wouldnt work, as there isnt a viewableItem beyond the final page.
You could use the FlatList onScroll
function to listen for swipes. When at the final page and a scroll event occurs, verify that it wasnt an attempt to go to the previous page and then navigate. e.g.
// store previous scroll values
const prevScroll = useRef({});
// scrollX, scrollY already contains the data
useEffect(()=>{
let isLastIndex = currentIndex == onBoardingData.length - 1;
let isScrollingToNextPage = scrollX > prevScroll.current.x
if( isLastIndex && isScrollingToNextPage ){
props.navigation.navigate("Login");
return
}
// store offsets
prevScroll.current = { x:scrollX, y:scrollY}
},[scrollX, scrollY])
If you would like for the old method to work you could just add an additional page (could be an empty view or a view with a small message)
--------OLD--------
Im assuming that OnBordingData
is an array since you're passing it to the Flatlist data prop. If so, then couldnt you add a conditional to your viewableItemsChanged
so that it goes to the login screen when at index > OnBoardingData.length - 1
? e.g
const viewableItemsChanged = useRef(({ viewableItems }: any) => {
const index = viewableItems[0].index;
if(index >= OnBoardinData.length -1){
// be sure to add props as a parameter to OnBoarding function
props.navigation.navigate("Login");
return
}
setCurrentIndex(index);
}).current;
--------OLD--------
Upvotes: -1