Wednesday, June 5, 2019

React Native Create Animated Accordion Panels using Layout Animation

This tutorial explains how to create animated accordion panel layout in react native application. Accordions are useful when you want to toggle between hiding and showing large amount of content. Accordion panels are automatically controlled by itself and if user clicks on single panel then it will smoothly slide down and open itself but if you have clicked on any closed panel then it will first close the already open panel and then open the clicked panel using animation. We are using React Native’s Layout Animation to to open and close the panel.
React Native Create Animated Accordion Panels using Layout Animation


React Native Accordion Collapsible & Expandable Example :

In this example we are going to create two components, First one defines the Accordion panel and another one is used to render that Accordion panel multiple times with different data for each panel in App component. Lets see the below example step by steps that helps to expand and collapse your content using accordion layout in react native application.

Project Structure : 

React Native Create Animated Accordion Panels using Layout Animation

Step 1: Create a new react native project, if you don’t know how to create a new project in react native just follow this tutorial.

Step 2: Create a new Accordion component inside the src folder. This component helps to expand and collapse user content, when user click on accordion panel.

Step 3: Through react , react-native  packages import all required components.
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';

Step 4: Lets create constructor block inside your Accordion component.
 constructor() {
        super();

        this.state = { updated_Height: 0 }
    }

Step 5: Lets implement componentWillReceiveProps and shouldComponentUpdate lifecycle hook function inside the Accordion component.
componentWillReceiveProps(update_Props) {
        if (update_Props.item.expanded) {
            this.setState(() => {
                return {
                    updated_Height: null
                }
            });
        }
        else {
            this.setState(() => {
                return {
                    updated_Height: 0
                }
            });
        }
    }

    shouldComponentUpdate(update_Props, nextState) {
        if (update_Props.item.expanded !== this.props.item.expanded) {
            return true;
        }
        return false;
    }

Step 6: Implement render method inside the Accordion class and wrapped the below layout design inside the root View component
render() {

        return (
            <View style={styles.accordionHolder}>

                <TouchableOpacity activeOpacity={0.7} onPress={this.props.onClickFunction} style={styles.Button}>
                    <Text style={styles.accordionButtonText}>{this.props.item.title} </Text>
                </TouchableOpacity>

                <View style={{ height: this.state.updated_Height, overflow: 'hidden' }}>
                    <Text style={styles.accordionText}>
                        {this.props.item.body}
                    </Text>
                </View>

            </View>
        );
    }

Step 7 : Apply the below style sheet design. 
const styles = StyleSheet.create({

    accordionText: {
        fontSize: 18,
        color: '#000',
        padding: 10
    },
    accordionButtonText: {
        textAlign: 'center',
        color: '#fff',
        fontSize: 21
    },
    accordionHolder: {
        borderWidth: 1,
        borderColor: '#FF6F00',
        marginVertical: 5
    },
    Button: {
        padding: 10,
        backgroundColor: '#FF6F00'
    }

Lets see the below complete source code for Accordion component.

Accordion.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';


export default class Accordion extends Component {

    constructor() {
        super();

        this.state = { updated_Height: 0 }
    }

    componentWillReceiveProps(update_Props) {
        if (update_Props.item.expanded) {
            this.setState(() => {
                return {
                    updated_Height: null
                }
            });
        }
        else {
            this.setState(() => {
                return {
                    updated_Height: 0
                }
            });
        }
    }

    shouldComponentUpdate(update_Props, nextState) {
        if (update_Props.item.expanded !== this.props.item.expanded) {
            return true;
        }
        return false;
    }

    render() {

        return (
            <View style={styles.accordionHolder}>

                <TouchableOpacity activeOpacity={0.7} onPress={this.props.onClickFunction} style={styles.Button}>
                    <Text style={styles.accordionButtonText}>{this.props.item.title} </Text>
                </TouchableOpacity>

                <View style={{ height: this.state.updated_Height, overflow: 'hidden' }}>
                    <Text style={styles.accordionText}>
                        {this.props.item.body}
                    </Text>
                </View>

            </View>
        );
    }
}

const styles = StyleSheet.create({

    accordionText: {
        fontSize: 18,
        color: '#000',
        padding: 10
    },
    accordionButtonText: {
        textAlign: 'center',
        color: '#fff',
        fontSize: 21
    },
    accordionHolder: {
        borderWidth: 1,
        borderColor: '#FF6F00',
        marginVertical: 5
    },
    Button: {
        padding: 10,
        backgroundColor: '#FF6F00'
    }

});

Step 8: Open App.js File in your favorite code editor and erase all code and follow this tutorial.

Step 9: Through react , react-native  packages import all required components.
import React, { Component } from 'react';
import { AppRegistry, LayoutAnimation, View, StyleSheet, Platform, ScrollView, UIManager, TouchableOpacity } from 'react-native';
import Accordion from "./src/components/Accordion.js"

Step 10: Lets create constructor block inside your App component.
constructor() {
    super();

    if (Platform.OS === 'android') {
      UIManager.setLayoutAnimationEnabledExperimental(true)
    }

    const array = [
      { expanded: false, title: "Section 1", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 2", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 3", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 4", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 5", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 6", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 7", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 8", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 9", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 10", body: "This is a simple example for Animated Accordion Panel." },
    ];

    this.state = { AccordionData: [...array] }
  }

Step 11: Lets create updateLayout function, which is responsible for expanding and collapsing animation effect in react component.

updateLayout = (index) => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    const array = this.state.AccordionData.map((item) => {
      const newItem = Object.assign({}, item);
      newItem.expanded = false;
      return newItem;
    });

    array[index].expanded = true;

    this.setState(() => {
      return { AccordionData: array }
    });
  }

Step 12: Implement render method inside the App class and wrapped the below layout design inside the root View component. 
render() {
    return (
      <View style={[styles.container, { backgroundColor: this.state.ColorHolder }]} >

        <ScrollView contentContainerStyle={{ paddingHorizontal: 10, paddingVertical: 5 }}>
          {
            this.state.AccordionData.map((item, key) =>
              (
                <Accordion key={key} onClickFunction={this.updateLayout.bind(this, key)} item={item} />
              ))
          }
        </ScrollView>

      </View>
    );
  }

Step 13 : Apply the below style sheet design. 
const styles = StyleSheet.create(
  {
    container: {
      flex: 1,
      justifyContent: "center",
      alignItems: "center",
    },
    
  });

Lets see the complete source code for App component.

App.js 
import React, { Component } from 'react';
import { AppRegistry, LayoutAnimation, View, StyleSheet, Platform, ScrollView, UIManager, TouchableOpacity } from 'react-native';
import Accordion from "./src/components/Accordion.js"

export default class App extends Component {

  constructor() {
    super();

    if (Platform.OS === 'android') {
      UIManager.setLayoutAnimationEnabledExperimental(true)
    }

    const array = [
      { expanded: false, title: "Section 1", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 2", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 3", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 4", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 5", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 6", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 7", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 8", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 9", body: "This is a simple example for Animated Accordion Panel." },
      { expanded: false, title: "Section 10", body: "This is a simple example for Animated Accordion Panel." },
    ];

    this.state = { AccordionData: [...array] }
  }

  updateLayout = (index) => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    const array = this.state.AccordionData.map((item) => {
      const newItem = Object.assign({}, item);
      newItem.expanded = false;
      return newItem;
    });

    array[index].expanded = true;

    this.setState(() => {
      return { AccordionData: array }
    });
  }

  render() {
    return (
      <View style={[styles.container, { backgroundColor: this.state.ColorHolder }]} >

        <ScrollView contentContainerStyle={{ paddingHorizontal: 10, paddingVertical: 5 }}>
          {
            this.state.AccordionData.map((item, key) =>
              (
                <Accordion key={key} onClickFunction={this.updateLayout.bind(this, key)} item={item} />
              ))
          }
        </ScrollView>

      </View>
    );
  }
}

const styles = StyleSheet.create(
  {
    container: {
      flex: 1,
      justifyContent: "center",
      alignItems: "center",
    },
    
  });

Screenshot : 

React Native Create Animated Accordion Panels using Layout Animation

React Native Create Animated Accordion Panels using Layout Animation

React Native Create Animated Accordion Panels using Layout Animation

This is all about React Native Create Animated Accordion Panels using Layout Animation. Thank you for reading this article, and if you have any problem, have a another better useful solution about this article, please write message in the comment section.

No comments:

Post a Comment