React Native Plant App UI #9 : Browse Screen

This tutorial is the ninth part of our React Native Plant App tutorial series. In the previous part, we successfully implemented the different UI sections of the SignUp Screen. This tutorial is the continuation of the same tutorial from where we left off in the last part. So, it is recommended to go through the previous part in order to get insight and knowledge of the overall project.

As mentioned in the previous parts, the tutorial series was inspired by the React Native App Templates that provide a wide variety of mobile application templates written in React Native and powered by universal features and design. These app templates allow us to implement our own apps and even start our own startups. And, this ninth part is also the continuation of coding implementations and designs from the Youtube video tutorial by React UI Kitfor the Plant App. The video tutorial delivers the coding implementation of the overall app very thoroughly. However, there is no verbal guidance for coding and implementation. Hence, this tutorial series is the implementation of the same coding style and designs in the form of the article. Thus, the learners can go through each step and take their time understanding the implementations.

Overview

In this ninth part of this tutorial series, we are going to implement some UI portions of the Browse screen. The Browse screen will contain three UI sections. The three UI sections are the header section, tabs section, and categories section. In this part, we are going to implement the header section which will contain the screen name and profile avatar. And, the tabs section which will contain three tab buttons. Lastly, we will implement the active tab button style as well.

So, let us begin!!

Simple React Native template for Browse screen

Here, we are going to add a simple template in the browse screen so that we can navigate to it.

But first, we need to uncomment the import and initialization of Browse screen in the index.js file of ‘./navigation/’ folder.

Then, in order to add the simple template to the Browse screen, we can use the code from the following code snippet in the Browse.js file:

import React from 'react';
import { StyleSheet } from 'react-native';
import { theme } from '../constants';
import { Button, Block, Text} from '../components';
export default class Browse extends React.Component {
  render(){
    return (
      <Block>
          <Text>Browse</Text>
      </Block>
    );
  }
  
}
const styles = StyleSheet.create({
});

Here, we have some imports from the react-native package and predefined custom components. Then, we have used the Block component which wraps the Text component as a template.

Hence, we will get the following result in the emulator screen:

As we can see, we can now navigate to Browse Screen after we tap on the login button.

Implementing the Header section

Here, we are going to implement the header section of the Browse screen. The header section is simple and consists of the screen name and the profile avatar. In order to implement the header section, we need to use the code from the following code snippet:

render(){
    return (
      <Block>
          <Block flex={false} row center space="between" style={styles.header}>
            <Text h1 bold>Browse</Text>
            <Button> </Button>
            </Block>
      </Block>
    );

Here, we have used the Block component with some style props. The Block component wraps the Text component and the Button component. The Text component is also configured with some style props. There is a style bound to Block component which is provided in the code snippet below:

header: {
  paddingHorizontal: theme.sizes.base * 2,
},

Hence, we will get the following result in the emulator screen:

Here, we have got the screen title in the header section. Now, we need to add the profile avatar.

Adding Profile Avatar

Here, we are going to add the profile avatar to the right side of the header section. For that, we need to import the profile data from the mock.js file of the ‘./constants/’ folder. For that, we need to add the following code to our Browse.js file:

import { theme, mocks } from '../constants';

Here, we have imported the mock data from mocks.js file as mocks. Now, we need to define the default prop and take in the profile data from the mocks variable. For that, we need to use the code from the following code snippet:

Browse.defaultProps = {
    profile : mocks.profile
}

Here, we have taken the profile data from mocks into the profile prop for the Browse screen. Now, need to define this profile prop inside the render() function:

render(){
    const { profile } = this.props;

Now, we are going to add an Image component with a profile image to the Button component which was empty. For that, we need to use the code from the following code snippet:

return (
      <Block>
          <Block flex={false} row center space="between" style={styles.header}>
            <Text h1 bold>Browse</Text>
            <Button>
                <Image source={profile.avatar} style={styles.avatar}/>
            </Button>
            </Block>
      </Block>
    );

Here, we have added the Image component with the source from profile and also consist of style. The required style is provided in the code snippet below:

avatar: {
  height: theme.sizes.base * 2.2,
  width: theme.sizes.base * 2.2,
},

Hence, we will get the following result in the emulator screen:

As we can see, we have got the profile avatar image on the right-hand side of the header section. This completes the implementation of the header section of our Browse screen.

Implementing Tabs Section

Now, we are going to start implementing the tabs section in our Browse section. This Tabs section will be placed just below the header section. It will contain three tab buttons. Later, we are going to add the active tab style as well as change the active tabs will taping on them.

But first, we need to define the tabs array with data which will be our tab titles. For that, we need to use the code from the following code snippet in the render() function:

const tabs = ['Products', 'Inspirations', 'Shop'];

Now, we need to define a new function called renderTab(). This function will return the template for the tabs section. For now, we are going to keep a simple template inside the renderTab() function as shown in the code snippet below:

renderTab(tab){
      return(
          <Text>{tab}</Text>
      )
  }

This function takes in a parameter that will represent the tab data. Now, we need to call this function to our render() function as shown in the code snippet below:

<Block>
      <Block flex={false} row center space="between" style={styles.header}>
        <Text h1 bold>Browse</Text>
        <Button>
            <Image source={profile.avatar} style={styles.avatar}/>
        </Button>
        </Block>
        <Block flex={false} row>
            {tabs.map(tab => this.renderTab(tab))}
        </Block>
  </Block>

Here, we have called the renderTab() function inside the Block component that is below the Block containing the header section template. In order to iterate through the tab data in the tabs array we have used the map() array function.

Hence, we will get the following result in our emulator screen:

As we can see, we have got the tab titles in the Browse screen. But, this does not look appealing at all. So, we are going to add some style configuration with additional components in order to make the tabs section more appealing.

Configuring Active state for Tabs

Here, we are going to define the active state in order to style the active tab. For the active tab style, we need to define a state variable called active which will handle the style of the active tab. For that, we need to use the code from the following code snippet:

state = {
     active: 'Products',
 }

Here, the active state is set to ‘Products’ tab from the tabs array. Now, we need to initialize this state inside the renderTab() function as shown in the code snippet below:

renderTab(tab){
        const { active } = this.state;
        const isActive = active === tab;
        return(
            <Text>{tab}</Text>
        )
    }

Here, we have defined a new constant called isActive and its value depends on the active state.

Configuring the Tab template

Here, we are going to add some addition predefined custom components as well as components from the react-native package in order to position and style the tabs section properly on the screen. For that, we need to use the code from the following code snippet in the renderTab() function:

renderTab(tab){
        const { active } = this.state;
        const isActive = active === tab;
        return(
            <TouchableOpacity
                key={tab-${tab}}
                style={[
                styles.tab,
                isActive ? styles.active : null
                ]}
            >
                <Text size={16} medium gray={!isActive} secondary={isActive}>
                {tab}
                </Text>
            </TouchableOpacity>
        )
    }

Here, we have added the TouchableOpacity component as the parent component which is configured with different props. The key prop to identify each tab uniquely. There are also style properties in which one depends on the isActive constant. The TouchableOpacity component wraps the Text component with some style prop as well. Some style props in the Text component also depend on the isActive constant.

Note that, we should remember to import necessary components being used from the react-native package like the TouchableOpacity component.

Now, in the render() function, we need to add some style to the Block wrapping the call of renderTab() function:

<Block flex={false} row style={styles.tabs}>
      {tabs.map(tab => this.renderTab(tab))}
  </Block>

The required styles in the renderTab() and render() functions are provided in the code snippet below:

tabs: {
   borderBottomColor: theme.colors.gray2,
   borderBottomWidth: 0.5,                    //for iOS : StyleSheet.hairLineWidth
   marginVertical: theme.sizes.base,
   marginHorizontal: theme.sizes.base * 2,
 },
 tab: {
   marginRight: theme.sizes.base * 2,
   paddingBottom: theme.sizes.base
 },
 active: {
   borderBottomColor: theme.colors.secondary,
   borderBottomWidth: 3,
 }

Hence, we will get the following result in the emulator screen:

As we can see, we have got the tabs section template which looks appealing. A tab also contains an active style.

Changing the Active tab when tapping

Here, we are going to change the active style from one tab to another based on which tab is pressed. For that, we need to use the code from the following code snippet in the renderTab() function:

<TouchableOpacity
    key={tab-${tab}}
    style={[
    styles.tab,
    isActive ? styles.active : null
    ]}
    onPress={() => this.setState({ active : tab})}
>
    <Text size={16} medium gray={!isActive} secondary={isActive}>
    {tab}
    </Text>
</TouchableOpacity>

Here, we have added the onPress event in the TouchableOpacity component. In the onPress event, we are changing the state of active state variable on the basis of tab that is being clicked.

Hence, we will get the following result in our emulator screen:

As we can see, we can now change the active style of the tab by tapping of each tab. Well, this completes for implementation of the Tabs section in the Browse screen. And with this, we have come to the end of this part of the tutorial.

In this part, we successfully completed the implementation of the header section and the tabs section in the Browse screen of React Native Plant UI App.

Conclusion

This tutorial is the ninth part of the React Native Plant App UI tutorial series. In this part, we continued from where we left off in the eighth part of this tutorial series. In this part of the tutorial, we learned to import the mock data and integrate it into the template to create the header section. We also got stepwise guidance on how to implement the overall tabs section with active style changes.

In the next part of this tutorial series, we are going to complete implementing the remaining UI section of our Browse screen which is the categories section.