In my project i did "handmade" tab bar without navigation.Firstly i preferred switch case, but now i understood, it cannot be without navigation.I want to change bottom tab navigation. Just i want to pass to other screens when i click bottom tabs but there is no function like "OnClick" in bottom tabs.My handmade router (App.js) menu takes some parameters something like that;
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import Login from './Login';
import Articles from './Articles';
import firebase from 'firebase';
import Loading from './Loading';
import Register from './Register';
import GotoSearch from './SearchItem';
import GiveDirection from './GiveDirection';
import Navigation from './Navigation';
class App extends Component {
constructor(props){
super(props);
this.setPage = this.setPage.bind(this);
this.setCurrentIndex = this.setCurrentIndex.bind(this);
this.setLastItem = this.setLastItem.bind(this);
this.state = { currentIndex: null, page: null, LastItem: {latitude : 0 , longitude : 0} };
}
state={
page:"login"
}
setPage(newpage) {
this.setState({page: newpage});
}
setCurrentIndex(id){
this.setState({currentIndex: id});
}
setLastItem(Item){
this.setState({LastItem:Item})
}
renderContent = () => {
switch (this.state.page) {
case "login":{
return <Login setPage={this.setPage}/>
}
case "articles":{
return <Articles
setPage={this.setPage}
setLastItem={this.setLastItem}
LastItem={this.state.LastItem}
/>
}
case "register":{
return <Register setPage={this.setPage}/>
}
case "gotosearch":{
return <GotoSearch
setPage={this.setPage}
currentIndex={this.state.currentIndex}
setCurrentIndex={this.setCurrentIndex} />
}
case "navigation":{
return <Navigation
setPage={this.setPage}
setLastItem={this.setLastItem}
LastItem={this.state.LastItem}
/>
}
case "givedirection":{
return <GiveDirection
setPage={this.setPage}
setLastItem={this.setLastItem}
LastItem={this.state.LastItem}
currentIndex={this.state.currentIndex}
setCurrentIndex={this.setCurrentIndex}
/>
}
default:
return <Loading />
}
}
I want to change from handmade menu to navigation menu
And this is the codes of the navigation menu I want to change
import React from 'react';
import { Text, View } from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { NavigationContainer } from '#react-navigation/native';
class HomeScreen extends React.Component {
/*constructor(props) {
super(props);
}
componentDidMount=() => {
this.props.setPage("articles");
}
*/
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SearchScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Search!</Text>
</View>
);
}
}
class LogoutScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Logout!</Text>
</View>
);
}
}
class RouteScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Route!</Text>
</View>
);
}
}
const Tab = createBottomTabNavigator();
const Tabs = () => {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Main" component={HomeScreen} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Logout" component={LogoutScreen} />
<Tab.Screen name="Route" component={RouteScreen} />
</Tab.Navigator>
</NavigationContainer>
)
}
export default Tabs;
Related
I am trying to navigate with React Navigate.
When clicking on the image I get this error in console:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I have tried different methods to navigate, but without success. Any suggestions?
This is my code:
import React, { Component } from 'react';
import { StyleSheet, Text, View, SafeAreaView, Image, TouchableHighlight } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { useNavigation } from '#react-navigation/native';
const Stack = createNativeStackNavigator();
import Home from './screens/homeScreen';
import Teams from './screens/teamsScreen';
export default class App extends Component {
GoTo({ screenName }) {
const navigation = useNavigation();
navigation.navigate(screenName);
}
render() {
return (
<SafeAreaView style={{flex: 1,}}>
<View style={styles.header}>
<TouchableHighlight onPress={() => this.GoTo('Teams')}>
<Image
style={styles.headerLogo}
source={{uri: 'https://yukigassen.no/uploads/Yukigassen_Logo_Big_Transparent.png'}}
resizeMode={'stretch'}
/>
</TouchableHighlight>
<View style={styles.headerRight}>
<Image
style={{width: 25, height: 25}}
source={{uri: 'https://icons.iconarchive.com/icons/dtafalonso/android-lollipop/512/Settings-icon.png'}}
/>
</View>
</View>
<View style={styles.screen}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={{headerShown: false}} />
<Stack.Screen name="Teams" component={Teams} options={{headerShown: false}} />
</Stack.Navigator>
</NavigationContainer>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
header: {
height: '7.5%',
padding: 5,
},
headerLogo: {
width: 160,
height: 50,
marginLeft: 10,
},
headerRight:{
position: 'absolute',
right: 5,
top: 15,
},
screen: {
flex: 1,
},
});
useNavigation() is a hook that cannot be used with class components but there is a way around it. You can create a wrapper component and pass the navigation prop into your class component.
class App extends Component {
render() {
// Get it from props
const { navigation } = this.props;
...
}
}
// Wrap and export
export default function(props) {
const navigation = useNavigation();
return <App {...props} navigation={navigation} />;
}
Example from https://reactnavigation.org/docs/use-navigation/
you can try this approach, make that comp default route and check, lemme know if this helps :) thanks
import React, { Component } from 'react';
import { StyleSheet, Text, View, SafeAreaView, Image, TouchableHighlight } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { useNavigation } from '#react-navigation/native';
const Stack = createNativeStackNavigator();
import Home from './screens/homeScreen';
import Teams from './screens/teamsScreen';
const DefaultRoute = () => {
GoTo({ screenName }) {
const navigation = useNavigation();
navigation.navigate(screenName);
}
return(
<SafeAreaView style={{flex: 1,}}>
<View style={styles.header}>
<TouchableHighlight onPress={() => this.GoTo('Teams')}>
<Image
style={styles.headerLogo}
source={{uri: 'https://yukigassen.no/uploads/Yukigassen_Logo_Big_Transparent.png'}}
resizeMode={'stretch'}
/>
</TouchableHighlight>
<View style={styles.headerRight}>
<Image
style={{width: 25, height: 25}}
source={{uri: 'https://icons.iconarchive.com/icons/dtafalonso/android-lollipop/512/Settings-icon.png'}}
/>
</View>
</View>
</SafeAreaView>
)
}
export default class App extends Component {
render() {
return (
<SafeAreaView style={styles.screen}>
<NavigationContainer>
<Stack.Navigator initialRouteName="DefaultRoute">
<Stack.Screen name="DefaultRoute" component={DefaultRoute} options={{headerShown: false}} />
<Stack.Screen name="Home" component={Home} options={{headerShown: false}} />
<Stack.Screen name="Teams" component={Teams} options={{headerShown: false}} />
</Stack.Navigator>
</NavigationContainer>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
header: {
height: '7.5%',
padding: 5,
},
headerLogo: {
width: 160,
height: 50,
marginLeft: 10,
},
headerRight:{
position: 'absolute',
right: 5,
top: 15,
},
screen: {
flex: 1,
},
});
I want to click the TouchableOpacity and set the state true so that will open. I am getting error. and how to align the button in center at the header? alignSelf is not working.
`
import React, {Component} from 'react';
import {
StyleSheet,
SafeAreaView,
View,
TouchableOpacity,
Text,
} from 'react-native';
import Menu from '../../src/components/menubar';
export default class SearchPage extends Component {
constructor(props) {
super(props);
this.state = {isMenubarDisplayed: false};
}
static navigationOptions = {
headerTitle: () => {
return (
<TouchableOpacity
onPress={()=> this.setState({isMenubarDisplayed: true})}>
<Icon name="search" size={20} color="#000" />
</TouchableOpacity>
);
},
headerTitleStyle: {
alignSelf: 'center',
flex: 1,
},
};
render() {
return (
<SafeAreaView style={styles.container}>
{this.state.isMenubarDisplayed ? (
<Menu />
) : null}
</SafeAreaView>
);
}
}`
You need to try this, expo-snack .
This is my below code for search.js ,
import * as React from 'react';
import { Text, View, StyleSheet,TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
import Menu from './menu';
import Icon from 'react-native-vector-icons/FontAwesome';
export default class Search extends React.Component {
constructor(props){
super(props);
this.state={
isMenubarDisplayed: false,
}
}
static navigationOptions = ({ navigation }) => {
return {
headerTitle: () => {
return (
<TouchableOpacity onPress={navigation.getParam('toggleMenu')}>
<Icon name="search" size={20} color="#000" />
</TouchableOpacity>
);
},
};
};
toggleMenu = () => {
this.setState({ isMenubarDisplayed: !this.state.isMenubarDisplayed})
}
renderMenu = () => (
<Menu />
)
componentDidMount(){
this.props.navigation.setParams({
toggleMenu: this.toggleMenu
});
}
render() {
return (
<View style={styles.container}>
{this.state.isMenubarDisplayed?this.renderMenu():<View></View>}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});
Hope it helps. feel free for doubts.
This is all you need https://reactnavigation.org/docs/en/header-buttons.html#header-interaction-with-its-screen-component
static navigationOptions = ({ navigation }) => {
return {
headerTitle: () => {
return (
<View style={{ flex: 1, alignItems: 'center' }}>
<TouchableOpacity onPress={navigation.getParam('toggleMenu')}>
<Icon name="search" size={20} color="#000" />
</TouchableOpacity>
</View>
);
},
};
};
componentDidMount() {
this.props.navigation.setParams({ toggleMenu: this.toggleMenu });
}
toggleMenu = () => {
this.setState({isMenubarDisplayed: true});
}
I am very new to React Native, but I have successfully made a little app that just consists of 2 different screens using react-navigation library.
My problem is that my App wont load when I try to use the UI library UI-Kitten. I'm positive that there's not anything wrong with the library but rather with my code.
This is my App.js:
import React from 'react';
import { mapping, light as lightTheme } from '#eva-design/eva';
import { ApplicationProvider, Layout, Text, Button } from 'react-native-ui-kitten';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import { fadeIn, fromTop, fromBottom, zoomIn, zoomOut } from 'react-navigation-transitions';
class HomeScreen extends React.Component {
render() {
return (
<Layout style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</Layout>
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
<Layout style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'black' }}>
<Text style={{color: 'white'}}>Details Screen</Text>
<Button
title='Back home'
color='white'
onPress={() => this.props.navigation.navigate('Home')}
/>
</Layout>
);
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
title: 'Home',
header: null
},
},
Details: {
screen: DetailsScreen,
navigationOptions: {
title: 'Details',
header: null
},
},
},
{
initialRouteName: 'Home',
transitionConfig: () => zoomIn(),
}
);
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
And this outputs this error when trying to launch:
https://pastebin.com/ygWFcgD0 (Long)
Thank you for ANY help or input on this problem!
You haven't configured the UI library correctly. The setup is outlined in the documentation.
Namely, see the mapping and theme props, as well the use of ApplicationProvider.
import React from 'react';
import { mapping, light as lightTheme } from '#eva-design/eva';
import { ApplicationProvider } from 'react-native-ui-kitten';
import { Application } from './path-to/application.component';
export default App = () => (
<ApplicationProvider
mapping={mapping}
theme={lightTheme}
<Application/>
</ApplicationProvider>
);
I need to create a simple layout.
I have a header component and beneath it I have a navigation tabs with content (see sketch - https://imgur.com/a/9H7FMYU).
I wish to achieve this with react navigation or react native navigation.
The reason I don't want to use react-native-tab-view is because it's not maintained and have a lot of bugs.
EDIT: I just found out that React navigation uses react-native-tab-view for displaying tabs. Therefore if you are looking for a solution, either use #user:568754 answer bellow or use react-native-tab-view with a header
I think what you are looking for is the MaterialTopTabNavigator component in react-navigation.
Here is some sample code:
import React from 'react';
import { Text, View } from 'react-native';
import { createMaterialTopTabNavigator, createStackNavigator, createAppContainer } from 'react-navigation';
class Head extends React.Component {
render() {
return (
<View style={{ height: 200, backgroundColor: 'blue' }}/>
);
}
}
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
const TabNavigator = createMaterialTopTabNavigator({
Home: HomeScreen,
Settings: SettingsScreen,
});
const RootNav = createAppContainer(TabNavigator);
class RootScreen extends React.Component {
render() {
return (
<View style={{ flex: 1 }}>
<Head />
<RootNav />
</View>
);
}
}
export default RootScreen;
And a link to an Expo snack to preview: https://snack.expo.io/#bra/creatematerialtoptabnavigator-example
I created a 3 page application with React native navigation. Admob ads are on the 3rd page. I want to try the same ad code on all three screens. If there is any idea in this matter, please share. Thank you.
For better understanding I give the following expo code.
import React, { Component } from 'react';
import {
WebView,
AppRegistry,
StyleSheet,
Text,
View,
Button,
Alert
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import ListComponent from './ListComponent';
class App extends Component {
static navigationOptions = {
title: 'App',
};
OpenSecondActivityFunction = () => {
this.props.navigation.navigate('Second');
};
render() {
return (
<View style={styles.container}>
<Button
onPress={this.OpenSecondActivityFunction}
title="Open Second Activity"
/>
</View>
);
}
}
class SecondActivity extends Component {
static navigationOptions = {
title: 'SecondActivity',
};
OpenThirdActivityFunction = data => {
this.props.navigation.navigate('Third');
};
render() {
return (
<View style={{ flex: 1 }}>
<ListComponent
OpenThirdActivityFunction={this.OpenThirdActivityFunction}
/>
</View>
);
}
}
class ThirdActivity extends Component {
static navigationOptions = {
title: 'ThirdSecondActivity',
};
render() {
return (
<View style={{ flex: 1 }}>
<Text>3</Text>
</View>
);
}
}
const ActivityProject = StackNavigator({
First: { screen: App },
Second: { screen: SecondActivity },
Third: { screen: ThirdActivity },
});
export default ActivityProject;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
Listcomponent.js
import React, { Component } from 'react';
import {
AppRegistry,
View,
Text,
FlatList,
ActivityIndicator,
} from 'react-native';
import { List, ListItem, SearchBar } from 'react-native-elements';
class ListComponents extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false,
};
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '98%',
backgroundColor: '#CED0CE',
marginLeft: '2%',
}}
/>
);
};
renderHeader = () => {
return <SearchBar placeholder="Type Here..." lightTheme round />;
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={[{ name: 1, coders: 2 }]}
renderItem={({ item }) => (
<ListItem
roundAvatar
title={`${item.name}`}
subtitle={item.coders}
containerStyle={{ borderBottomWidth: 0 }}
onPress={() => this.props.OpenThirdActivityFunction(item.coders)}
/>
)}
keyExtractor={item => item.coders}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
/>
</List>
);
}
}
export default ListComponents;