Place Material Top Tab Navigator at custom location - android

Using createMaterialTopTabNavigator in react navigation, I have achieved the following:
However, I want to move the tabs below the page title bar and above the job item slider carousel. How do I achieve this? Here is my code:
export const MaterialTabNavigation = createMaterialTopTabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarLabel: "Home"
}
},
PopularJobs: {
screen: PopularJobs,
navigationOptions: {
tabBarLabel: "Popular"
}
},
Wishlist: {
screen: Wishlist,
navigationOptions: {
tabBarLabel: "Wishlist"
}
}
},
{
initialRouteName: 'Home',
tabBarOptions: {
activeTintColor: primaryColor,
inactiveTintColor: '#000000',
upperCaseLabel: false,
pressColor: '#efefef',
tabBarPosition: 'top',
indicatorStyle: {
backgroundColor: primaryColor,
height: 2,
},
labelStyle: {
fontSize: 15,
},
tabStyle: {
height: 32,
marginHorizontal: 15,
},
style: {
backgroundColor: '#ffffff',
borderBottomWidth: 0,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 0,
},
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0,
}
}
},
);

You shouldn't export createAppContainer(TabNavigator) like what Docs says, instead you should put createAppContainer(TabNavigator) in a const and use it like a React Component like code below:
export default class HomeScreen extends Component<{}> {
render () {
return (
<View>
// your other views
<TabLayout />
</View>
);
}
}
class OneScreen extends Component<{}> {
render () {
return (
<View>
<Text>One</Text>
</View>
);
}
}
class TwoScreen extends Component<{}> {
render () {
return (
<View>
<Text>Two</Text>
</View>
);
}
}
class ThreeScreen extends Component<{}> {
render () {
return (
<View>
<Text>Three</Text>
</View>
);
}
}
const TabNavigator = createMaterialTopTabNavigator({
One: {
screen: OneScreen,
navigationOptions: {
tabBarLabel: "One"
}
},
Two: {
screen: TwoScreen,
navigationOptions: {
tabBarLabel: "Two"
}
},
Three: {
screen: ThreeScreen,
navigationOptions: {
tabBarLabel: "Three"
}
}
},
);
const TabLayout = createAppContainer(TabNavigator);

Related

React Native: expected a string (for built-in components) or a class/function (for composite components) but got: object

I am trying to change the Header Title to an image, but I can't get it to work. What I have tried is use the LogoTitle class to render an image instead of a title in my Top Tab Navigator, hiding the header works and rendering a title works also:
TopNavigator.navigationOptions = {
headerTitle:'test'
};
And then I tried to change it to an image:
TopNavigator.navigationOptions = () =>{
headerTitle:<LogoTitle/>
};
I use the latest Expo SDK
This is my full code:
import React from 'react';
import { createStackNavigator, createMaterialTopTabNavigator } from 'react-navigation';
import TabBarIcon from '../components/TabBarIcon';
import PartyScreen from '../screens/PartyScreen';
import EventScreen from '../screens/EventScreen';
import FestivalScreen from '../screens/FestivalScreen';
import ActivityScreen from '../screens/ActivityScreen';
import TestScreen from '../screens/TestScreen';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require('../assets/images/Header_Logo.png')}
style={{ width: '100%', height: '100%', resizeMode: 'center', backgroundColor: 'black' }}
/>
);
}
}
const PartyStack = createStackNavigator({
Party: PartyScreen,
});
PartyStack.navigationOptions = {
tabBarLabel: "Partys",
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const EventStack = createStackNavigator({
Event: EventScreen,
});
EventStack.navigationOptions = {
tabBarLabel: 'Events',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const FestivalStack = createStackNavigator({
Festival: FestivalScreen,
});
FestivalStack.navigationOptions = {
tabBarLabel: 'Festivals',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const ActivityStack = createStackNavigator({
Activity: ActivityScreen,
});
ActivityScreen.navigationOptions = {
tabBarLabel: 'Activiteit',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const TestStack = createStackNavigator({
Test: TestScreen,
});
TestScreen.navigationOptions = {
tabBarLabel: 'Test',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
'md-calendar'
}
/>
),
};
const TopNavigator = createMaterialTopTabNavigator({
PartyStack,
EventStack,
FestivalStack,
ActivityStack,
TestStack
}, {
tabBarOptions: {
activeTintColor: '#5B71F9',
inactiveTintColor: '#888888',
showIcon: false,
labelStyle: {
fontSize: 14
},
scrollEnabled : true,
style: {
backgroundColor: '#fff',
shadowColor: '#fff',
shadowOffset: {
width: 0,
height: 0,
},
shadowOpacity: 0,
shadowRadius: 0,
elevation: 0,
height: 47,
borderBottomWidth: 1,
borderBottomColor: '#E8E8E8'
},
indicatorStyle: {
height: 2,
backgroundColor: '#5B71F9'
},
},
}, navigationOptions = {
header:{visible:false}
});
TopNavigator.navigationOptions = {
headerTitle:<LogoTitle/>
};
export default TopNavigator;
I don't get why it does render Text but images wont, I guess it has to do with the brackets
try this:
const RouteConfigs = {
// Your routes
};
const StackNavigatorConfig = {
navigationOptions: {
header: (navigation) => ({
title: ( <LogoTitle navigation={navigation} /> )
})
},
};
export default createStackNavigator(RouteConfigs, StackNavigatorConfig);

Open a modal on BottomTabNavigator click react-native

I was trying to open a modal from bottomnavigator , was following this tutorial - https://snack.expo.io/SyJKMkFUM
I am using react-navigation -3.0.9
here is my app.js
class App extends React.Component {
renderItem = (route, index) => {
const {
navigation,
jumpToIndex,
} = this.props;
const isCapture = route.routeName === 'Capture';
const focused = index === navigation.state.index;
return (
<TouchableWithoutFeedback
key={route.key}
onPress={() => isCapture ? this.props.navigation.navigate('CaptureModal') : jumpToIndex(index)}
>
<View >
<Text >{route.routeName}</Text>
</View>
</TouchableWithoutFeedback>
);
};
render() {
const {
navigation,
} = this.props;
const {
routes,} = navigation.state;
return (
<View style={styles.container}>
{routes && routes.map(this.renderItem)}
</View>
);}}
const Screen = (props) => (
<View >
<Text>{props.title} Screen</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
const TabNavigator = createBottomTabNavigator({
Home: {
screen: HomeScreen
},
Link: {
screen: LinksScreen
},
settings: {
screen: View,
},
});
const CaptureStack = createStackNavigator({
Capture: {
screen: (props) => <Screen title="Capture" {...props} />,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Capture',
headerLeft: (
<Button
title="Back"
onPress={() => navigation.goBack(null)}
/>),}),},})
const RootStack1 = createStackNavigator({
Main: {
screen: TabNavigator,
},
CaptureModal: {
screen: CaptureStack,
navigationOptions: {
gesturesEnabled: false,
},
},
}, {
headerMode: 'none',
mode: 'modal',
});
const AppNavigator = createAppContainer(RootStack1);
export default AppNavigator;
Could anyone please explain what is wrong with this ? Could it be a routing version issue as the tutorial is using 1.0.0 .
I did solve my issue if anyone is lokking here how i achieved it -
My Goal ->
Click on Main Screen -> Tabbed Activity -> on click of any tab new screen
in my app.js i created navigation as follows -
const TabNavigator = createBottomTabNavigator({
HomeScreen: {
screen: HomeScreen
},
LinksScreen: {
screen: LinksScreen
},
LoginScreen: {
screen: SurveyScreen,
},
},
{
initialRouteName : 'HomeScreen' ,
});
const RootStack1 = createStackNavigator({
TabNavigator: {
screen: TabNavigator,
},
CaptureModal: {
screen: LoginScreen,
navigationOptions: {
gesturesEnabled: false,
},
},
}, {
headerMode: 'none',
mode: 'modal',
headerLeft: null
});
const mainStack = createStackNavigator({
InsideApp: {
screen: MainScreen,
},
StartScreen: {
screen: RootStack1,
},
} ,{
headerMode: 'none',
headerLeft: null
},);
const AppNavigator = createAppContainer(mainStack);
export default AppNavigator;
Now My Modal screen will pop up on click of third tab (SurveyScreen) , to achieve that inside surveyscreen all i had to do was override didmount function and open modal from there -
componentDidMount() {
console.log('didmount called.');
this.props.navigation.navigate('CaptureModal')
}
For back navigation from modal to tab activity i used stackreset -
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'TabNavigator' })],
});
and click of back -
onPress={ () => this.props.navigation.dispatch(resetAction)

React Native:- Swipe gesture is not working on drawernavigator of react-navigation

I am new to react native and i am trying to make screen which has two tabs and one drawer. For this i am using createTabnavigator inside createDrawerNavigator and this createDrawerNavigator inside createStackNavigator. I have enabled the swipeEnable but still the swipe gesture is not working for drawer but the tabs are working fine. Please help me to find a way to make this work.
Here is the set up of createDrawernavigator.
App.js
import React from "react";
import { TouchableOpacity } from "react-native";
import { connect } from "react-redux";
import {
createDrawerNavigator,
createStackNavigator,
createAppContainer,
createMaterialTopTabNavigator
} from "react-navigation";
import Icon from "react-native-vector-icons/MaterialIcons";
import { DrawerActions } from "react-navigation-drawer";
import Login from "./modules/LoginPage/components/Form";
import NewComplaint from "./modules/newComplaint/components/Form";
import OpenTab from "./modules/homePage/components/OpenTab";
import ClosedTab from "./modules/homePage/components/CloseTab";
import complaintDetails from
"./modules/ComplaintDetail/components/Details";
const App = props =>
// eslint-disable-next-line react/prop-types
props.authentication.data.success ? (
<LoginRootStack />
) : (
<LoggedOutRootStack />
);
const Drawer = createDrawerNavigator(
{
OpenComplaints: createMaterialTopTabNavigator(
{
Open: { screen: OpenTab },
Closed: { screen: ClosedTab }
},
{
order: ["Open", "Closed"],
initialRouteName: "Open"
}
),
ClosedComplaints: createMaterialTopTabNavigator(
{
Open: { screen: OpenTab },
Closed: { screen: ClosedTab }
},
{
order: ["Open", "Closed"],
initialRouteName: "Closed"
}
)
},
{
navigationOptions: ({ navigation }) => ({
title: "Home",
drawerLockMode: "unlocked",
headerLeft: (
<TouchableOpacity
style={{ marginLeft: 10 }}
onPress={() => {
navigation.dispatch(DrawerActions.toggleDrawer());
}}
>
<Icon name="menu" size={30} color="#fff" navigation={navigation}
/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
style={{ marginRight: 10 }}
onPress={() => {
navigation.navigate("newComplaint");
}}
>
<Icon name="add" size={30} color="#fff" navigation={navigation} />
</TouchableOpacity>
),
headerStyle: {
backgroundColor: "#2980b9"
},
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold"
}
}),
swipeEnabled: true,
contentOptions: {
activeTintColor: "#2980b9"
}
}
);
const LoggedOutStack = createStackNavigator(
{
Login: { screen: Login },
Home: { screen: Drawer },
newComplaint: { screen: NewComplaint },
Details: { screen: complaintDetails }
},
{
swipeEnabled: true,
initialRouteName: "Login",
headerMode: "none"
}
);
const LogggedInStack = createStackNavigator(
{
Login: { screen: Login },
Home: { screen: Drawer },
newComplaint: { screen: NewComplaint },
Details: { screen: complaintDetails }
},
{
swipeEnabled: true,
initialRouteName: "Home"
}
);
function mapStateToProps(state) {
return {
authentication: state.authentication
};
}
export const LoginRootStack = createAppContainer(LogggedInStack);
export const LoggedOutRootStack = createAppContainer(LoggedOutStack);
export default connect(mapStateToProps)(App);
Put LoggedOutStack and LogggedInStack in switchStackNavigator and put that switchStackNavigator in createAppContainer.

how to use LinearGradient for react tab navigator tabs

I have a react tabnavigator which i used it from ReactNavigation(v2) component:
const Tab = createMaterialTopTabNavigator({
Nearest: {
screen: Nearest, navigationOptions: {
tabBarLabel: 'myprofile'
}
},
Recomanded: {
screen: Recomanded, navigationOptions: {
tabBarLabel: 'recomanded'
}
},
Home: {
screen: Hotest, navigationOptions: {
tabBarLabel: 'hotest'
}
},
},
{
tabBarOptions: {
labelStyle: {
fontSize: 12,
fontFamily:"IRANSans"
},
tabStyle: {
backgroundColor: '#ef6102',
}
}
}
);
now i want to use linear gradient for Tabs color but i couldn't find any way to do it!...how its possible ? how can i take the tabs inside this tag:
<LinearGradient colors={['#EF7D2F', '#C8191A']}>..here..</LinearGradient>
You should add custom view for your tab by using tabBarCompontent:
const Tab = createMaterialTopTabNavigator({
Nearest: {
screen: Nearest, navigationOptions: {
tabBarLabel: 'myprofile'
}
},
Recomanded: {
screen: Recomanded, navigationOptions: {
tabBarLabel: 'recomanded'
}
},
Home: {
screen: Hotest, navigationOptions: {
tabBarLabel: 'hotest'
}
},
},
{
tabBarComponent:(props)=>{
return(<TabBar {...props}></TabBar>)},<<<<<<<look here<<<<<<<<
tabBarOptions: {
labelStyle: {
fontSize: 12,
fontFamily:"IRANSans"
},
tabStyle: {
backgroundColor: '#ef6102',
}
}
}
);
for example TabBar is a component like this:
const TabBar=(props)=> {
return (
<LinearGradient colors={['#EF7D2F', '#C8191A']}>..here..
</LinearGradient>
);
}
you can use this as a reference

React Native - Modal is showing on a different FlatList screen

I'am having trouble with modal because I have some in a "Datails screen" with Flatlist and it is working fine, actually. But the thing is, before navigating to my "Datails screen" the user will first see the "Category screen", and here is where the problem. Because I didn't type any modal at my "Category screen", but whenever I click on any button in there a modal is showing, it looks very tricky for me.
Here is my code
Details.js (this is the only screen where I want to display my modal)
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl, Dimensions, Modal
} from 'react-native';
export default class Details extends Component {
static navigationOptions = {
title: ''
};
constructor()
{
super ()
this.state = {
showModal: true
}
}
state = {
data: [],
refreshing: false
};
fetchData = async() => {
const { params } = this.props.navigation.state;
const response_Cat = await fetch('http://192.168.254.100:3307/categories/' + params.id);
const category_Cat = await response_Cat.json();
this.setState({data: category_Cat});
};
componentDidMount() {
this.fetchData();
};
_onRefresh() {
this.setState({ refreshing: true });
this.fetchData().then(() => {
this.setState({ refreshing: false })
});
};
render() {
const { params } = this.props.navigation.state;
return (
<View style = { styles.container }>
<FlatList
data = { this.state.data }
renderItem = {({ item }) =>
<TouchableOpacity style = { styles.buttonContainer }>
<Text style = { styles.buttonText }
onPress = { () => { this.setState({showModal:true}) } }>{ item.menu_desc } { item.menu_price }</Text>
</TouchableOpacity>
}
keyExtractor={(item, index) => index.toString()}
/*refreshControl = {
<RefreshControl
refreshing = { this.state.refreshing }
onRefresh = { this._onRefresh.bind(this) }
/>
}*/
/>
<View>
<Modal
onRequestClose={() => console.warn('no warning')}
visible={this.state.showModal}
>
<TouchableOpacity style = { styles.buttonContainer }>
<Text style = { styles.buttonText }
onPress = { () => { this.setState({ showModal:false }) } }>Hello</Text>
</TouchableOpacity>
</Modal>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
pageName:{
margin:10,fontWeight:'bold',
color:'#000', textAlign:'center'
},
productBox:{
padding:5,margin:10,borderColor:'orange',borderBottomWidth:1
},
price:{
padding:5, color:'orange',fontWeight:'bold',textAlign:'center'
},
proName:{
padding:5,color:'blue',textAlign:'center'
},
buttonContainer: {
backgroundColor: '#f7c744',
paddingVertical: 10,
borderRadius: 30,
marginBottom: 10,
},
buttonText: {
textAlign: "center",
color: 'rgb(32, 53, 70)',
fontWeight: 'bold',
fontSize: 18
},
modalView: {
backgroundColor: "#aaa",
height: 150,
justifyContent: 'center',
alignItems: 'center'
},
closeText: {
backgroundColor: '#333',
color: '#bbb',
padding: 5,
margin: 20
}
})
//AppRegistry.registerComponent('Details', () => Details);
categories.js (this is the page where I don't type any modal code, I guess)
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl
} from 'react-native';
export default class Categories extends Component {
state = {
data: [],
refreshing: false
};
fetchData = async() => {
const { params } = this.props.navigation.state;
const response_Cat = await fetch('http://192.168.254.100:3307/categories/');
const category_Cat = await response_Cat.json();
this.setState({data: category_Cat});
};
componentDidMount() {
this.fetchData();
};
_onRefresh() {
this.setState({ refreshing: true });
this.fetchData().then(() => {
this.setState({ refreshing: false })
});
}
render() {
const { params } = this.props.navigation.state;
return (
<View style = { styles.container }>
<FlatList
data = { this.state.data }
renderItem = {({ item }) =>
<TouchableOpacity style = {styles.buttonContainer}>
<Text style = {styles.buttonText}
onPress = { () => this.props.navigation.navigate('Details', { id: item.cat_id }) }>{ item.cat_name }</Text>
</TouchableOpacity>
}
keyExtractor={(item, index) => index.toString()}
refreshControl = {
<RefreshControl
refreshing = { this.state.refreshing }
onRefresh = { this._onRefresh.bind(this) }
/>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
pageName:{
margin:10,fontWeight:'bold',
color:'#000', textAlign:'center'
},
productBox:{
padding:5,margin:10,borderColor:'orange',borderBottomWidth:1
},
price:{
padding:5, color:'orange',fontWeight:'bold',textAlign:'center'
},
proName:{
padding:5,color:'blue',textAlign:'center'
},
buttonContainer: {
backgroundColor: '#f7c744',
paddingVertical: 10,
borderRadius: 30,
marginBottom: 10,
},
buttonText: {
textAlign: "center",
color: 'rgb(32, 53, 70)',
fontWeight: 'bold',
fontSize: 18
},
})
AppRegistry.registerComponent('Categories', () => Categories);
In your details.js you kept showModal: true in constructor itself.
Change it to false, and make it true whenever you want to show a modal.
I guess you should make it true after you have successfully fetched data. i.e keep it in fetchData()
this.setState({data: category_Cat, showModal:true});

Categories

Resources