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

(React Native) How to keep animated component in new place after initial animation

$
0
0

I have a <TextInput> which, when the user enters anything into, will have a button appear from behind it.

This works fine using the Animated library from react, but each time I input text into the area, the animation "rubber bands" up and down.

My question is: How can I keep the button in place after the initial animation happens?

I still need to monitor whether the text box is empty in order to decide whether to show or hide the button.

My code:

import { View, TextInput, StyleSheet, Animated, TouchableOpacity } from "react-native";import { useState } from "react";import CurrencyInput from 'react-native-currency-input';import { Ionicons } from "@expo/vector-icons";type expenseItemData = {  item:string;  costAndSign:string;  cost:number | null;}type Props = {    sendItem:  ({ item, cost, costAndSign }: expenseItemData) => void;}const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);const AddAndConfirmExpense: React.FC<Props>  = ({sendItem}) => {    const [animation] = useState(new Animated.Value(-58));    const [expenseValue, setExpenseValue] = useState<number>(0.00);    const [expenseItem, setExpenseItem] = useState<string>("");    const [expenseValueAndSign, SetExpenseValueAndSign] = useState<string>("");    const [buttonLayoutPersistence, setButtonLayoutPersistence] = useState({        bottom:0    });    const [validExpenseItem, setValidExpenseItem] = useState<boolean>(false);    const onChangeExpenseItem = (text: string) => {        setExpenseItem(text);        if (text.trim().length === 0) {            setValidExpenseItem(false);            hideButton();            setButtonLayoutPersistence({bottom:0})            return;        }        if (validExpenseItem) {            setButtonLayoutPersistence({bottom:-48})            return        };        showButton();        setValidExpenseItem(true);    };    const onButtonPress = () => {        const newData:expenseItemData = {            item:expenseItem,            costAndSign:expenseValueAndSign,            cost:expenseValue        }         sendItem(newData);    };    const setAreaDynamicStyling = () => {        if (validExpenseItem) {            return {                borderTopRightRadius:5,                 borderTopLeftRadius:5,                backgroundColor:"#f5f5f5"            }        }        return {borderRadius:5};    };    const setButtonDynamicStyling = () => {        if (!validExpenseItem) return {borderRadius:5}        return {borderBottomLeftRadius: 5,borderBottomRightRadius:5}    };    const animatedStyle = {transform: [{translateY:animation}],};    const showButton = () => {        Animated.timing(animation, {            toValue: -10,            duration: 1000,            useNativeDriver: true,        }).start();    }    const hideButton = () => {        Animated.timing(animation, {            toValue: -58,            duration: 500,            useNativeDriver: true,        }).start();    }    return (<View><View style={validExpenseItem ? [styles.inputsContainer, setAreaDynamicStyling()] : [styles.inputsContainer,styles.shadowProp,setAreaDynamicStyling()]}><TextInput                style={styles.textInputArea}                placeholder='Item'                placeholderTextColor="#aaaaaa"                onChangeText={(text) => {onChangeExpenseItem(text)}}                value={expenseItem}                underlineColorAndroid="transparent"                autoCapitalize="none"            /><View style={styles.verticalLine}/><CurrencyInput                 style={styles.currencyInputArea}                value={expenseValue}                onChangeValue={setExpenseValue}                prefix="£"                delimiter=","                separator="."                precision={2}                minValue={0}                onChangeText={(formattedValue) => {                    SetExpenseValueAndSign(formattedValue)                }}            /></View><AnimatedTouchable onPress={()=>{onButtonPress()}} style={[{flex:1, zIndex:-1},animatedStyle]}><View style={[styles.confirmInputContainer, setButtonDynamicStyling(), buttonLayoutPersistence]}>    <Ionicons name="checkmark-circle-outline" size={24} color="white" /></View></AnimatedTouchable></View>    )}const styles = StyleSheet.create({    confirmInputContainer:{        backgroundColor:"#7f96ff",        height: 48,        flexDirection:"row",        paddingVertical:10,        justifyContent:"center",    },    inputsContainer:{        backgroundColor:"white",        height: 48,        flexDirection:"row",        paddingVertical:10,        marginVertical:10,        justifyContent:"space-between",       },    shadowProp: {        shadowColor: '#353935',        shadowOffset: {width: -2, height: 4},        shadowOpacity: 0.2,        shadowRadius: 4,      },    textInputArea:{        width:"60%",        maxWidth:"60%",        marginLeft:20,    },    verticalLine:{        height: "100%",        width: 1,        backgroundColor: "#909090",        marginHorizontal:5,    },    currencyInputArea:{        maxWidth:"20%",        width:"20%",        marginRight:20    },})export default AddAndConfirmExpense;

Viewing all articles
Browse latest Browse all 6290

Trending Articles



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