Monday, June 17, 2019

React Native dynamically Toggle between Grid View and List View

This tutorial explains how to create dynamically toggle between grid view and list view using FlatList component in react native application. This feature enhances the user experience for end user and allows developer to create attractive designs. I think you may have been seen this kind of toggle switching effect in mobile or web based application specially in retail and shopping application. In this example we are going to create toggle switching between grid and list view in react native app.

React Native dynamically Toggle between Grid View and List View


React Native dynamically Toggle between Grid View and List View :

Lets see the complete source code App.js component that helps to create dynamically toggle between grid view and list view using FlatList component in react native application




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: Open App.js File in your favorite code editor and erase all code and follow this tutorial.

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

Step 3:  Lets create the ImageComponent component inside the App.js file. This component is responsible to displaying or render thumbnail/image inside the FlatList Component.
class ImageComponent extends Component {

  constructor() {
    super();
  }
  render() {
    return (
      <View style={styles.imageHolder}>
        <Image source={{ uri: this.props.imageURI }} style={styles.image} />
        <View style={styles.textViewHolder}>
          <Text numberOfLines={1} style={styles.textOnImage}>
            {this.props.name}
          </Text>
        </View>
      </View>
    );
  }
}

Step 4 : Now create a constructor block inside the App component.
constructor() {
    super();
    this.state = { imagesData: null, loading: true, gridView: true, btnText: 'Show List' }
  }

Step 5 : Create componentDidMount lifecycle hook method, this method will retrieve the images from the server with help of fetch function and update the state variable.
componentDidMount() {
    fetch('https://picsum.photos/v2/list?page=2&limit=30')
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({ imagesData: responseJson, loading: false });
      })
      .catch((error) => {
        console.error(error);
      });
  }

Step 6 : Create changeView function inside your App component. This function is responsible toggle switching between grid view and list view.
changeView = () => {
    this.setState({ gridView: !this.state.gridView }, () => {
      if (this.state.gridView) {
        this.setState({ btnText: 'Show List' });
      }
      else {
        this.setState({ btnText: 'Show Grid' });
      }
    });
  }

Step 7: Implement render method inside the App class and wrapped the below layout design inside the root View component. 
render() {
    return (
      <View style={styles.container} >
        {
          (this.state.loading)
            ?
            (<View style={styles.loadingContainer}>
              <ActivityIndicator size="large" />
              <Text style={styles.loadingText}>Please Wait...</Text>
            </View>)
            :
            (<View style={{ flex: 1 }}>

              <TouchableOpacity activeOpacity={0.8} style={styles.buttonDesign} onPress={this.changeView}>
                <Text style={styles.buttonText}>{this.state.btnText}</Text>
              </TouchableOpacity>

              <FlatList keyExtractor={(item) => item.id}
                key={(this.state.gridView) ? 1 : 0}
                numColumns={this.state.gridView ? 2 : 1}
                data={this.state.imagesData}
                renderItem={({ item }) =>
                  <ImageComponent imageURI={item.download_url} name={item.author.toUpperCase()} />
                } />

            </View>)
        }
      </View>
    );
  }

Step 8: Apply the below style sheet design. 
const styles = StyleSheet.create(
  {
    container: {
      flex: 1,
    },
    imageHolder: {
      margin: 5,
      height: 160,
      flex: 1,
      position: 'relative'
    },
    image: {
      height: '100%',
      width: '100%',
      resizeMode: 'cover'
    },
    textViewHolder: {
      position: 'absolute',
      left: 0,
      bottom: 0,
      right: 0,
      backgroundColor: 'rgba(0,0,0,0.75)',
      paddingHorizontal: 10,
      paddingVertical: 13,
      alignItems: 'center'
    },
    textOnImage: {
      color: 'white'
    },
    loadingContainer: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center'
    },
    loadingText: {
      paddingTop: 10,
      fontSize: 18,
      color: 'black'
    },
    buttonDesign: {
      padding: 15,
      backgroundColor: '#e91e63'
    },
    buttonText: {
      color: 'white',
      textAlign: 'center',
      alignSelf: 'stretch'
    }
  });

Complete Source Code for App.js 

Lets see the complete source code that helps to create dynamically toggle between grid view and list view using FlatList component in react native.

import React, { Component } from 'react';
import { AppRegistry, TouchableOpacity, Image, FlatList, ActivityIndicator, StyleSheet, View, Platform, Text } from 'react-native';

class ImageComponent extends Component {

  constructor() {
    super();
  }
  render() {
    return (
      <View style={styles.imageHolder}>
        <Image source={{ uri: this.props.imageURI }} style={styles.image} />
        <View style={styles.textViewHolder}>
          <Text numberOfLines={1} style={styles.textOnImage}>
            {this.props.name}
          </Text>
        </View>
      </View>
    );
  }
}

export default class App extends Component {

  constructor() {
    super();
    this.state = { imagesData: null, loading: true, gridView: true, btnText: 'Show List' }
  }

  componentDidMount() {
    fetch('https://picsum.photos/v2/list?page=2&limit=30')
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({ imagesData: responseJson, loading: false });
      })
      .catch((error) => {
        console.error(error);
      });
  }

  changeView = () => {
    this.setState({ gridView: !this.state.gridView }, () => {
      if (this.state.gridView) {
        this.setState({ btnText: 'Show List' });
      }
      else {
        this.setState({ btnText: 'Show Grid' });
      }
    });
  }

  render() {
    return (
      <View style={styles.container} >
        {
          (this.state.loading)
            ?
            (<View style={styles.loadingContainer}>
              <ActivityIndicator size="large" />
              <Text style={styles.loadingText}>Please Wait...</Text>
            </View>)
            :
            (<View style={{ flex: 1 }}>

              <TouchableOpacity activeOpacity={0.8} style={styles.buttonDesign} onPress={this.changeView}>
                <Text style={styles.buttonText}>{this.state.btnText}</Text>
              </TouchableOpacity>

              <FlatList keyExtractor={(item) => item.id}
                key={(this.state.gridView) ? 1 : 0}
                numColumns={this.state.gridView ? 2 : 1}
                data={this.state.imagesData}
                renderItem={({ item }) =>
                  <ImageComponent imageURI={item.download_url} name={item.author.toUpperCase()} />
                } />

            </View>)
        }
      </View>
    );
  }
}

const styles = StyleSheet.create(
  {
    container: {
      flex: 1,
    },
    imageHolder: {
      margin: 5,
      height: 160,
      flex: 1,
      position: 'relative'
    },
    image: {
      height: '100%',
      width: '100%',
      resizeMode: 'cover'
    },
    textViewHolder: {
      position: 'absolute',
      left: 0,
      bottom: 0,
      right: 0,
      backgroundColor: 'rgba(0,0,0,0.75)',
      paddingHorizontal: 10,
      paddingVertical: 13,
      alignItems: 'center'
    },
    textOnImage: {
      color: 'white'
    },
    loadingContainer: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center'
    },
    loadingText: {
      paddingTop: 10,
      fontSize: 18,
      color: 'black'
    },
    buttonDesign: {
      padding: 15,
      backgroundColor: '#e91e63'
    },
    buttonText: {
      color: 'white',
      textAlign: 'center',
      alignSelf: 'stretch'
    }
  });

Screenshot : 

React Native dynamically Toggle between Grid View and List View


React Native dynamically Toggle between Grid View and List View

This is all about React Native dynamically Toggle between Grid View and List ViewThank 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.

1 comment: