Search code examples
reactjsreact-nativereact-native-flexbox

Change active state and flex transition


I have a react component class like below

<View style={{flex: 1}}>
    <TouchableOpacity style={styles.FreeCoffee}/>
    <TouchableOpacity style={styles.Help}/>
</View>

both touchableopacity components have the value of flex 2 so they equally divided in window. When one of the touchableopacity pressed, I want to make a transition between flex to 2 into 4 so that one box can grow with animation, also mark it as a "active" or "selected" one. I have searched this many many times but since I am a beginner in ReactNative, I couldn't find any proper way to that.

Is this possible or achiveable ?

//Edit Full Code

import React from 'react'
import {ScrollView, Text, View, TouchableOpacity, Button} from 'react-native'
import styles from '../Styles/Containers/HomePageStyle'


export default class HomePage extends React.Component {
    constructor(props){
        super(props);

        /*this.state = {
            active : { flex : 8 }
        }*/
    }

    render() {
        return (
            <View style={styles.mainContainer}>
                <View style={{flex: 1}}>
                    <TouchableOpacity style={styles.FreeCoffee}/>
                    <TouchableOpacity style={styles.Help}/>
                </View>
            </View>
        )
    }
    componentWillMount(){

    }
    animateThis(e) {

    }
}

Solution

  • You can use LayoutAnimation to do this. Define state that toggles the styles that are applied to your render and use onPress in the TouchableOpacity to define your function that Calls the LayoutAnimation and setState. Something like the following:

        import React from 'react';
        import { LayoutAnimation, ScrollView, StyleSheet, Text, View, TouchableOpacity, Button } from 'react-native';
        // import styles from '../Styles/Containers/HomePageStyle'
    
        const styles = StyleSheet.create({
          mainContainer: {
            flexGrow: 1,
          },
          FreeCoffee: {
            backgroundColor: 'brown',
            flex: 2,
          },
          Help: {
            backgroundColor: 'blue',
            flex: 2,
          },
          active: {
            flex: 4,
            borderWidth: 1,
            borderColor: 'yellow',
          },
        });
    
        export default class HomeContainer extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              active: 'neither',
            };
            this.setActive = this.setActive.bind(this);
          }
          setActive(active) {
            // tells layout animation how to handle next onLayout change...
            LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
    
            // set active in state so it triggers render() to re-render, so LayoutAnimation can do its thing
            this.setState({
              active,
            });
          }
          render() {
            return (
              <View style={styles.mainContainer}>
                <View style={{ flex: 1, backgroundColor: 'pink' }}>
                  <TouchableOpacity
                    style={[
                      styles.FreeCoffee,
                      (this.state.active === 'FreeCoffee') && styles.active]}
                    onPress={() => {
                      this.setActive('FreeCoffee');
                    }}
                  />
                  <TouchableOpacity
                    style={[
                      styles.Help,
                      (this.state.active === 'Help') && styles.active]}
                    onPress={() => {
                      this.setActive('Help');
                    }}
                  />
                </View>
              </View>
            );
          }
        }