Problem with transition between components with React Native Animated

Viewed 68

I have 2 View component, each of them I want to show only one per time.

The transition I want to achieve is slide left and right.

The problem is that the second View which is by default not visible, when I fire my function to change components, it wont appears at the correct position.

import {StyleSheet, Text, View, Animated, Dimensions} from 'react-native';
import React, {useRef, useState} from 'react';
import {Colors, Typography} from 'styles';
import {OutlineButton, TextMedium, TextRegular} from 'component/global';
import {Pen} from 'utils/icon_assets';

const {width, height} = Dimensions.get('window');
const UserInfo = ({data}) => {
    //Animation Functions
    const offsetUserInfo = useRef(new Animated.Value(0)).current;
    const offsetEditUser = useRef(new Animated.Value(width)).current;
    const opacityUserInfo = useRef(new Animated.Value(1)).current;
    const opacityEdituser = useRef(new Animated.Value(0)).current;

    const onPressUpdate = () => {
        Animated.parallel([
            Animated.timing(offsetUserInfo, {
                toValue: -width,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(opacityUserInfo, {
                toValue: 0,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(offsetEditUser, {
                toValue: 0,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(opacityEdituser, {
                toValue: 1,
                duration: 300,
                useNativeDriver: false,
            }).start(),
        ]);
    };

    const onPressSave = () => {
        Animated.parallel([
            Animated.timing(offsetUserInfo, {
                toValue: 0,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(opacityUserInfo, {
                toValue: 1,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(offsetEditUser, {
                toValue: width,
                duration: 300,
                useNativeDriver: false,
            }).start(),
            Animated.timing(opacityEdituser, {
                toValue: 0,
                duration: 300,
                useNativeDriver: false,
            }).start(),
        ]);
    };

    return (
        <View style={styles.Wrapper}>
            <View style={styles.Row}>
                <TextMedium text={'Data Diri'} size={Typography.FONT_SIZE_16} />
                <OutlineButton
                    textButton="Update"
                    style={styles.ButtonEdit}
                />
                <OutlineButton
                    textButton="Save"
                    style={styles.ButtonEdit}
                />
            </View>
            <View
                style={{
                    flex: 1,
                    overflow: 'hidden',
                    flexDirection: 'row',
                }}>
                <Animated.View
                    style={[
                        styles.BodyWrapper,
                        {
                            transform: [
                                {
                                    translateX: offsetUserInfo,
                                },
                            ],
                            opacity: opacityUserInfo,
                            backgroundColor: 'yellow',
                        },
                    ]}>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Nama Lengkap'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={data?.fullName ? data?.fullName : 'Mark zuck'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Email'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.email
                                    ? data?.email
                                    : 'johndoe@example.com'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Nomor HP'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.phoneNumber
                                    ? data?.phoneNumber
                                    : '0812345678'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Alamat Lengkap'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.address
                                    ? data?.address
                                    : 'Jl. Bulungan No. 26, RT.11/RW.7, Kramat Pela, Kec. Kby. Baru, Daerah Khusus Ibukota Jakarta 12130'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                            style={{width: '80%'}}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Catatan Alamat'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.detailAddress
                                    ? data?.detailAddress
                                    : 'Rumah Pagar Oren'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                            style={{width: '80%'}}
                        />
                    </View>
                </Animated.View>

                <Animated.View
                    style={[
                        styles.BodyWrapper,
                        {
                            transform: [
                                {
                                    translateX: offsetEditUser,
                                },
                            ],
                            opacity: opacityEdituser,
                        },
                    ]}>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Nama Lengkap'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={data?.fullName ? data?.fullName : 'John Doe'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Email'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.email
                                    ? data?.email
                                    : 'johndoe@example.com'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Nomor HP'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.phoneNumber
                                    ? data?.phoneNumber
                                    : '0812345678'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Alamat Lengkap'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.address
                                    ? data?.address
                                    : 'Jl. Bulungan No. 26, RT.11/RW.7, Kramat Pela, Kec. Kby. Baru, Daerah Khusus Ibukota Jakarta 12130'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                            style={{width: '80%'}}
                        />
                    </View>
                    <View style={styles.Column}>
                        <TextMedium
                            text={'Catatan Alamat'}
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N100}
                        />
                        <TextMedium
                            text={
                                data?.detailAddress
                                    ? data?.detailAddress
                                    : 'Rumah Pagar Oren'
                            }
                            size={Typography.FONT_SIZE_12}
                            color={Colors.N400}
                            style={{width: '80%'}}
                        />
                    </View>
                </Animated.View>
            </View>
        </View>
    );
};

export default UserInfo;

const styles = StyleSheet.create({
    Wrapper: {
        flex: 1,
        borderWidth: 1,
        borderRadius: 8,
        borderColor: Colors.N30,
        paddingHorizontal: 16,
        paddingVertical: 20,
        backgroundColor: Colors.N0,
        marginTop: 12,
    },
    Row: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
    },
    ButtonEdit: {
        paddingVertical: 6,
        paddingHorizontal: 18,
    },
    BodyWrapper: {
        marginTop: 28,
        width: width * 0.8,
        backgroundColor: 'red',
    },
    Column: {
        marginBottom: 16,
    },
});

Current result that I got is :

enter image description here

As you can see theres a huge gap between each View. View with red background is not fully positioned inside my screen

What did I do wrong ?

1 Answers

You can use horizontal FlatList instead and call scrollToIndex() function to navigate between items.

About your question, most probably this happens due to the position issues. You have either position those two views absolutely, or just use 1 animated view, which you will change position from 0 to -width and vice-versa

Related