M Ansyori
M Ansyori

Reputation: 488

How to Create Top Navigation Tab Under Another Component in React Native?

I'm using react-navigation version 5, currently, I have a screen with Text and Button inside a View which placed at the top of the SafeAreaView, and I need to add TopTabNavigator just below the View.

Here's the code:

TimelineComponent.js

import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';

class TimelineComponent extends React.PureComponent {
  render() {
    return (
      <ScrollView>
        <Text>Timeline</Text>
      </ScrollView>
    );
  }
}

export default TimelineComponent;

TrendingComponent.js

import React from 'react';
import PropTypes from 'prop-types';
import {ScrollView, Text} from 'react-native';

class TrendingComponent extends React.PureComponent {
  render() {
    return (
      <ScrollView>
        <Text>Trending</Text>
      </ScrollView>
    );
  }
}

export default TrendingComponent;

TopNav.js

import React from 'react';

import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
import TimelineComponent from '../TimelineComponent';
import TrendingComponent from '../TrendingComponent';

const Tab = createMaterialTopTabNavigator();

export function TopNav() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Timeline" component={TimelineComponent} />
      <Tab.Screen name="Trending" component={TrendingComponent} />
    </Tab.Navigator>
  );
}

WallFragmentComponent.js

import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
  Keyboard,
  SafeAreaView,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View,
} from 'react-native';
import {TopNav} from './TopNav';

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  header_container: {
    backgroundColor: 'white',
    alignItems: 'center',
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  header_text: {
    fontSize: 30,
    fontWeight: '500',
  },
  new_chat_button: {
    alignItems: 'center',
    borderColor: 'blue',
    borderWidth: 1,
    borderRadius: 12,
    display: 'flex',
    flexDirection: 'row',
    paddingHorizontal: 22,
    paddingTop: 6,
    paddingVertical: 6,
  },
  top_nav: {
    marginVertical: 20,
  },
});

class WallFragmentComponent extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      input: {},
      secureTextEntry: true,
    };
  }

  handleInput = (name, value) => {
    this.setState({
      input: {...this.state.input, [name]: value},
    });
  };
  render() {
    return (
      <View style={{backgroundColor: 'white'}}>
        <SafeAreaView>
          <TouchableWithoutFeedback
            onPress={Keyboard.dismiss}
            accessible={false}>
            <View style={styles.container}>
              <View style={styles.header_container}>
                <Text style={styles.header_text}>Wall</Text>
                <TouchableOpacity style={styles.new_chat_button}>
                  <Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
                  <Text style={{fontWeight: '500', color: 'blue'}}>
                    New Post
                  </Text>
                </TouchableOpacity>
              </View>
            </View>
          </TouchableWithoutFeedback>
          <View style={styles.top_nav}>
            <TopNav />
          </View>
        </SafeAreaView>
      </View>
    );
  }
}

export default WallFragmentComponent;

In the WallFragmentComponent.js file, I have placed <TopNav /> inside a View, but it's not rendering when I run the project. Here's the screenshot: screenshot

How am I able to add top navigation just under the Wall Text and New Post button? any help will be much appreciated.

Thank you, Regards

Upvotes: 0

Views: 734

Answers (3)

Ezekolo
Ezekolo

Reputation: 11

I found a simple solution to this. Your code is working well but you only need to style the View component holding your TopNav.

Try setting a fixed height of 200 on the <View style={styles.top_nav}> <TopNav /> </View> component.

`styles.top_nav: {height: 200}`

Later on, you can play with values such as flex: 1

Upvotes: 1

M Ansyori
M Ansyori

Reputation: 488

Well, finally I have found the solution:

  1. Change the first <View ... /> element into <SafeAreaView style={{flex: 1}} /> and then everything is working correctly.

WallFragmentComponent.js

import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';
import {
  Keyboard,
  SafeAreaView,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View,
} from 'react-native';
import {TopNav} from './TopNav';

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  header_container: {
    backgroundColor: 'white',
    alignItems: 'center',
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  header_text: {
    fontSize: 30,
    fontWeight: '500',
  },
  new_chat_button: {
    alignItems: 'center',
    borderColor: 'blue',
    borderWidth: 1,
    borderRadius: 12,
    display: 'flex',
    flexDirection: 'row',
    paddingStart: 22,
    paddingEnd: 22,
    paddingTop: 6,
    paddingBottom: 6,
  },
  top_nav: {
    marginTop: 20,
  },
});

class WallFragmentComponent extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      input: {},
      secureTextEntry: true,
    };
  }

  handleInput = (name, value) => {
    this.setState({
      input: {...this.state.input, [name]: value},
    });
  };
  render() {
    return (
      <SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
        <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
          <View style={styles.container}>
            <View style={styles.header_container}>
              <Text style={styles.header_text}>Wall</Text>
              <TouchableOpacity style={styles.new_chat_button}>
                <Icon name="comment" style={{marginEnd: 6, color: 'blue'}} />
                <Text style={{fontWeight: '500', color: 'blue'}}>
                  {' '}
                  New Post
                </Text>
              </TouchableOpacity>
            </View>
          </View>
        </TouchableWithoutFeedback>
        <TopNav />
      </SafeAreaView>
    );
  }
}

export default WallFragmentComponent;

Screenshot

And that's it

Upvotes: 1

Nooruddin Lakhani
Nooruddin Lakhani

Reputation: 6967

This might help

// TopNav.js
  
const Tab = createMaterialTopTabNavigator();

const AppNavigator = () => {

  return (
     <Tab.Navigator>
       <Tab.Screen name="Timeline" component={TimelineComponent} />
       <Tab.Screen name="Trending" component={TrendingComponent} />
     </Tab.Navigator>
  )
}

  
export default AppNavigator;

WallFragmentComponent.js

import AppNavigator from './AppNavigator';
...........

const TopNav = createAppContainer(AppNavigator);

class WallFragmentComponent extends React.PureComponent { 
......
render() {
    return (
      <View style={{backgroundColor: 'white'}}>
        ......
            <TopNav />
        ......
      </View>
    );
  }
}

You can also use react-native-scrollable-tab-view

Upvotes: 1

Related Questions