React Native Dynamically Change ProgressBar Progress on ScrollView Scrolling Andorid iOS Tutorial

Guys, In this tutorial I am going to explain and show you how we can Dynamically Change ProgressBar Progress on ScrollView Scrolling in react native. Basically, this tutorial demonstrates how we can identify that how much scroll view has been scrolled in either top or down side.

In brief, what I am doing in Dynamically Change ProgressBar Progress on ScrollView Scrolling tutorial?

  • Basically to perform this task I require these following three values:
    • ScrollView height.
    • ScrollView content’s height.
    • ScrollView’s current scrolling position.

And react native ScrollView component provides sufficient props for these tasks and these props are as follows:

  • To get the ScrollView height, we have to use the onLayout prop.
  • To get the ScrollView content’s height, we have to use the onContentSizeChange prop.
  • To get the ScrollView’s current scrolling position, the react native ScrollView component provides onScroll prop, which takes a function with event parameter and this function executes every time when we scroll the ScrollView and through this event parameter we can get the ScrollView’s current scrolling position.

Let’s begin…

Step – 1: Import required components from react , react-native packages.

import React, { Component } from 'react';
import { Text, View, StyleSheet, ScrollView, Platform, ProgressBarAndroid, ProgressViewIOS } from 'react-native';

Step – 2: Implement constructor  method.

constructor()
{
    super();

    this.scrollViewHeight = 0;

    this.scrollViewContentHeight = 0;

    this.state = { scrollPercent: 0 }
}

Explanation:

  • this.scrollViewHeight  variable is used to hold the outer height of the ScrollView Component.
  • this.scrollViewContentHeight  variable is used to hold the inner content height of the ScrollView Component.

Step – 3: Implement onScroll  custom method which will be executed every time when you scroll the ScrollView and in this method our calculation will be performed.

onScroll = ( event ) =>
{
    this.setState({ scrollPercent: Math.abs( event.nativeEvent.contentOffset.y / ( this.scrollViewContentHeight - this.scrollViewHeight ))});
}

Explanation:

  • Suppose our ScrollView height is 640 and our ScrollViewContentHeight is 2416 and contentOffset value is 180 then according to above formula, scrollPercent  state variable will hold the value 0.10 then when we convert this value into percent then we will get 10% then it means our ScrollView component has been 10% scrolled and this calculation will be done every time when we scroll the ScrollView component to get the updated value.

Step – 3: Implement render method.

render()
{
    return(
        <View style = { styles.container }>
            <ScrollView onScroll = { this.onScroll } contentContainerStyle = {{ paddingBottom: 40 }} onLayout = {(event) => this.scrollViewHeight = ( event.nativeEvent.layout.height )} onContentSizeChange = {( width, height ) => { this.scrollViewContentHeight = height }} scrollEventThrottle = { 16 }>
                <Text style = { styles.text }>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula justo non libero tristique, nec scelerisque arcu rutrum. Vestibulum leo turpis, bibendum at nulla ut, elementum fringilla felis. Vivamus est orci, laoreet ut scelerisque sit amet, rutrum ut mi. Aliquam a sagittis tellus. Vestibulum pulvinar felis odio, vel ornare massa vehicula et. Curabitur ut accumsan metus. In tempus iaculis ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum laoreet turpis tellus, sit amet condimentum neque efficitur ac. Sed lobortis id orci et malesuada. Nunc sit amet nibh aliquam, elementum nulla rutrum, blandit nisi. Vestibulum et justo in augue tristique consectetur. Praesent varius elit eget urna consectetur eleifend. Duis non lacus vitae ante vestibulum condimentum non et est.

                    Cras mattis eu neque eu ornare. Etiam blandit risus facilisis urna feugiat, et facilisis ligula fermentum. Etiam tempor neque eget arcu euismod, quis semper felis eleifend. Sed semper maximus nunc in laoreet. Curabitur rutrum tortor ac ipsum faucibus convallis. Ut hendrerit iaculis neque, ut tincidunt nunc aliquet nec. Maecenas vel varius felis. Proin fermentum justo ac dolor tincidunt, at mattis ipsum malesuada. Pellentesque ac tempor neque, eu accumsan urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

                    Phasellus et est aliquet, commodo urna eu, rutrum arcu. Pellentesque venenatis tortor ut posuere molestie. Vivamus auctor sem a blandit bibendum. Maecenas sodales mauris semper finibus viverra. Aenean diam leo, molestie ac lorem vel, molestie semper sapien. Nullam fringilla bibendum tortor sit amet commodo. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In a imperdiet nisi. Vivamus ultricies facilisis felis, sed suscipit turpis sagittis id. Etiam maximus lobortis tellus. Pellentesque vestibulum ornare commodo.

                    Integer dignissim eget odio eu tincidunt. Aenean quis pulvinar lacus. Aenean vitae vulputate magna, pharetra gravida velit. Proin interdum augue id libero auctor convallis. Vivamus id metus mi. Nullam neque felis, rhoncus elementum lorem vel, ultrices efficitur sapien. Praesent ut sem aliquet, semper sem in, porta leo. Morbi tempus mi vitae laoreet faucibus. Morbi vel ullamcorper lectus, ac auctor augue. Pellentesque sagittis libero tortor, id malesuada libero venenatis ac. Morbi gravida felis pharetra, sollicitudin magna et, condimentum lectus. Nunc eu diam ut eros euismod hendrerit vel sed lorem. Nunc sit amet pharetra lectus, rhoncus bibendum nulla. Sed nunc arcu, faucibus nec bibendum quis, eleifend sit amet velit. Curabitur egestas mi eget ex vulputate efficitur. Nulla ullamcorper augue eu pretium rutrum.

                    Phasellus aliquam lacus euismod dolor pellentesque ultricies. Aenean erat justo, mattis at leo quis, scelerisque malesuada eros. In nec lectus ut turpis faucibus suscipit. Cras tincidunt vulputate mi, pharetra sollicitudin est. Ut vehicula pulvinar porta. Curabitur eu convallis tortor. Donec elit risus, fermentum ut urna non, cursus tincidunt purus. Quisque vel malesuada purus. Curabitur tristique cursus nisi. Vivamus eu lectus ex. Morbi sit amet porta sem. Maecenas eu magna nibh. Mauris ultricies nibh sed diam venenatis, non interdum libero faucibus. Cras ut turpis vitae est luctus sodales. Aliquam elit felis, tempor ac leo sed, tempor posuere justo.
                </Text>
            </ScrollView>

            <View style = { styles.bottomViewHolder }>
            {   
                ( Platform.OS === 'android' )
                ?
                    (
                        <ProgressBarAndroid
                            progress = { this.state.scrollPercent }
                            styleAttr = "Horizontal"
                            color = "white"
                            indeterminate = { false }
                            style = {{ width: '100%' }}
                        />
                    )
                :
                    (
                        <ProgressViewIOS
                            progress = { this.state.scrollPercent }
                            progressTintColor = "white"
                            style = {{ width: '100%' }}
                        />
                    )
            }
                <Text style = { styles.percentText }>{ Math.round( this.state.scrollPercent * 100 ) }%</Text>
            </View>
        </View>
    );
}
Note: I am rendering different components on different platforms using Platform API because ProgressBarAndroid component works on Android platform and ProgressViewIOS component works on iOS platform.

Step – 4: Implement styles for all required components.

const styles = StyleSheet.create(
{
    conatainer:
    {
        flex: 1,
        paddingTop: ( Platform.OS === 'ios' ) ? 20 : 0
    },

    percentText:
    {
        position: 'absolute',
        right: 15,
        fontWeight: 'bold',
        color: 'white'
    },

    text:
    {
        fontSize: 20,
        color: 'black',
        padding: 15,
        textAlign: 'left'
    },
    
    bottomViewHolder:
    {
      paddingLeft: 15,
      paddingRight: 55,
      position: 'absolute',
      bottom: 0,
      left: 0,
      right: 0,
      backgroundColor: 'black',
      height: 40,
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center'
    }
});

Complete Source Code:

import React, { Component } from 'react';
import { Text, View, StyleSheet, ScrollView, Platform, ProgressBarAndroid, ProgressViewIOS } from 'react-native';

export default class App extends Component<{}>
{
    constructor()
    {
        super();

        this.scrollViewHeight = 0;

        this.scrollViewContentHeight = 0;

        this.state = { scrollPercent: 0 }
    }

    onScroll = ( event ) =>
    {
        this.setState({ scrollPercent: Math.abs( event.nativeEvent.contentOffset.y / ( this.scrollViewContentHeight - this.scrollViewHeight ))});
    }

    render()
    {
        return(
            <View style = { styles.container }>
                <ScrollView onScroll = { this.onScroll } contentContainerStyle = {{ paddingBottom: 40 }} onLayout = {(event) => this.scrollViewHeight = ( event.nativeEvent.layout.height )} onContentSizeChange = {( width, height ) => { this.scrollViewContentHeight = height }} scrollEventThrottle = { 16 }>
                    <Text style = { styles.text }>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula justo non libero tristique, nec scelerisque arcu rutrum. Vestibulum leo turpis, bibendum at nulla ut, elementum fringilla felis. Vivamus est orci, laoreet ut scelerisque sit amet, rutrum ut mi. Aliquam a sagittis tellus. Vestibulum pulvinar felis odio, vel ornare massa vehicula et. Curabitur ut accumsan metus. In tempus iaculis ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum laoreet turpis tellus, sit amet condimentum neque efficitur ac. Sed lobortis id orci et malesuada. Nunc sit amet nibh aliquam, elementum nulla rutrum, blandit nisi. Vestibulum et justo in augue tristique consectetur. Praesent varius elit eget urna consectetur eleifend. Duis non lacus vitae ante vestibulum condimentum non et est.

                        Cras mattis eu neque eu ornare. Etiam blandit risus facilisis urna feugiat, et facilisis ligula fermentum. Etiam tempor neque eget arcu euismod, quis semper felis eleifend. Sed semper maximus nunc in laoreet. Curabitur rutrum tortor ac ipsum faucibus convallis. Ut hendrerit iaculis neque, ut tincidunt nunc aliquet nec. Maecenas vel varius felis. Proin fermentum justo ac dolor tincidunt, at mattis ipsum malesuada. Pellentesque ac tempor neque, eu accumsan urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;

                        Phasellus et est aliquet, commodo urna eu, rutrum arcu. Pellentesque venenatis tortor ut posuere molestie. Vivamus auctor sem a blandit bibendum. Maecenas sodales mauris semper finibus viverra. Aenean diam leo, molestie ac lorem vel, molestie semper sapien. Nullam fringilla bibendum tortor sit amet commodo. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In a imperdiet nisi. Vivamus ultricies facilisis felis, sed suscipit turpis sagittis id. Etiam maximus lobortis tellus. Pellentesque vestibulum ornare commodo.

                        Integer dignissim eget odio eu tincidunt. Aenean quis pulvinar lacus. Aenean vitae vulputate magna, pharetra gravida velit. Proin interdum augue id libero auctor convallis. Vivamus id metus mi. Nullam neque felis, rhoncus elementum lorem vel, ultrices efficitur sapien. Praesent ut sem aliquet, semper sem in, porta leo. Morbi tempus mi vitae laoreet faucibus. Morbi vel ullamcorper lectus, ac auctor augue. Pellentesque sagittis libero tortor, id malesuada libero venenatis ac. Morbi gravida felis pharetra, sollicitudin magna et, condimentum lectus. Nunc eu diam ut eros euismod hendrerit vel sed lorem. Nunc sit amet pharetra lectus, rhoncus bibendum nulla. Sed nunc arcu, faucibus nec bibendum quis, eleifend sit amet velit. Curabitur egestas mi eget ex vulputate efficitur. Nulla ullamcorper augue eu pretium rutrum.

                        Phasellus aliquam lacus euismod dolor pellentesque ultricies. Aenean erat justo, mattis at leo quis, scelerisque malesuada eros. In nec lectus ut turpis faucibus suscipit. Cras tincidunt vulputate mi, pharetra sollicitudin est. Ut vehicula pulvinar porta. Curabitur eu convallis tortor. Donec elit risus, fermentum ut urna non, cursus tincidunt purus. Quisque vel malesuada purus. Curabitur tristique cursus nisi. Vivamus eu lectus ex. Morbi sit amet porta sem. Maecenas eu magna nibh. Mauris ultricies nibh sed diam venenatis, non interdum libero faucibus. Cras ut turpis vitae est luctus sodales. Aliquam elit felis, tempor ac leo sed, tempor posuere justo.
                    </Text>
                </ScrollView>

                <View style = { styles.bottomViewHolder }>
                {   
                    ( Platform.OS === 'android' )
                    ?
                        (
                            <ProgressBarAndroid
                                progress = { this.state.scrollPercent }
                                styleAttr = "Horizontal"
                                color = "white"
                                indeterminate = { false }
                                style = {{ width: '100%' }}
                            />
                        )
                    :
                        (
                            <ProgressViewIOS
                                progress = { this.state.scrollPercent }
                                progressTintColor = "white"
                                style = {{ width: '100%' }}
                            />
                        )
                }
                    <Text style = { styles.percentText }>{ Math.round( this.state.scrollPercent * 100 ) }%</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create(
{
    conatainer:
    {
        flex: 1,
        paddingTop: ( Platform.OS === 'ios' ) ? 20 : 0
    },

    percentText:
    {
        position: 'absolute',
        right: 15,
        fontWeight: 'bold',
        color: 'white'
    },

    text:
    {
        fontSize: 20,
        color: 'black',
        padding: 15,
        textAlign: 'left'
    },
    
    bottomViewHolder:
    {
      paddingLeft: 15,
      paddingRight: 55,
      position: 'absolute',
      bottom: 0,
      left: 0,
      right: 0,
      backgroundColor: 'black',
      height: 40,
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center'
    }
});

Step – 5: Apply react-native run-android  command on terminal to run app in Android devices or use react-native run-ios  to run app in iOS devices.

Enjoy Guys…

Leave a Reply

Your email address will not be published. Required fields are marked *