React native navigation custom tabbar icon - react-native

Is this possible to have custom component ( Button or what ever ) instead of simple icon in tab bar?
I need to set my tab bar icon dynamically like this
this.props.navigator.setTabButton({
tabIndex: 0,
icon: <Icon name="heart" size={28} /> <--- not appear
});
OR we can use only icons? Any solutions?

Yes, it is possible. I am sharing my solution as code below:
const renderNav = (routeName, focused) => {
return (
<View style={{
flex: 1,
width: 90,
justifyContent: 'center',
alignItems: 'center',
borderTopColor: StylesGeneric.COLORS.primary,
borderTopWidth: focused ? 4 : 0,
}}>
<Text
style={[StylesGeneric.STYLES.footerText]}>
{routeName}
</Text>
</View>
);
};
const customTabs = ({navigation}) => ({
tabBarIcon: ({focused}) => {
const {routeName} = navigation.state;
if (routeName === 'Home') {
return renderNav('Home', focused);
} else if (routeName === 'Profile') {
return renderNav('Profile', focused);
} else if (routeName === 'ProfileOther') {
return renderNav('ProfileOther', focused);
}
},
});
const nav = createBottomTabNavigator(
{
Home: {
screen: Home,
},
Profile: {
screen: Profile,
},
ProfileOther: {
screen: ProfileOther,
},
},
{
defaultNavigationOptions: customTabs,
animationEnabled: true,
swipeEnabled: true,
tabBarPosition: 'bottom',
initialRouteName: 'Home',
tabBarOptions: {
showLabel: false,
style: {
borderTopColor: 'transparent',
backgroundColor: StylesGeneric.COLORS.white,
height: StylesGeneric.FOOTER_HEIGHT,
},
},
},
);
const AppContainer = createAppContainer(nav);

Related

How to add a drawer navigator React-Navigation v4

I have this code for creating a drawer navigator. But I can't open my drawer through left to right slide. Can anyone please help me to solve my problem. I am new to react-native. I am using react-navigation v4 and react-navigation-drawer for the drawer navigator.
const EMBotomTabScreen = createDrawerNavigator ({
SUMMARY: {
screen : EMNavigator,
navigationOptions :{
animationEnabled : 'true',
// headerLeft : <HamburgerIcon navigationProps={ navigation }/>,
swipeEnabled: true,
tabBarOptions: {
activeTintColor: '#369841',
//activeBackgroundColor : '#f2f2f2',
inactiveTintColor : 'gray',
inactiveBackgroundColor : '#adc1b8',
borderRightWidth:2,
borderRightColor:'blue',
labelStyle: {
fontSize: 13,
},
style: {
backgroundColor: '#f2f2f2',
// borderRightWidth:2,
// borderRightColor:'blue'
},
indicatorStyle: {
backgroundColor: 'red',
},
},
tabStyle: {
backgroundColor: 'green',
borderRightWidth:2,
borderRightColor:'blue'
},
indicatorStyle : {
backgroundColor : 'red'
},
tabBarIcon: ({ focused, tintColor }) => {
const iconName = `ios-desktop`;
return <Image source={require('../assets/aaaaa.png')} size={27} color={tintColor} />;
},
}
},
DEMAND: {
screen : EMDemandNavigator,
navigationOptions : {
tabBarOptions: {
activeTintColor: '#369841',
// activeBackgroundColor : '#f2f2f2',
inactiveTintColor : 'gray',
inactiveBackgroundColor : '#adc1b8',
labelStyle: {
fontSize: 13,
},
style: {
backgroundColor: '#f2f2f2',
},
},
tabBarIcon: ({ focused, tintColor }) => {
const iconName = `ios-cloud`;
return <Image source={require('../assets/aaaaaaa.png')} size={27} color={tintColor} />;
},
}
},
ALARM: {
screen : EMAlarmNavigator,
navigationOptions : {
animationEnabled : 'true',
swipeEnabled: true,
tabBarOptions: {
activeTintColor: '#369841',
//activeBackgroundColor : '#f2f2f2',
inactiveTintColor : 'gray',
inactiveBackgroundColor : '#adc1b8',
borderRightWidth:2,
borderRightColor:'blue',
labelStyle: {
fontSize: 13,
},
style: {
backgroundColor: '#f2f2f2',
// borderRightWidth:2,
// borderRightColor:'blue'
},
indicatorStyle: {
backgroundColor: 'red',
},
},
tabStyle: {
backgroundColor: 'green',
borderRightWidth:2,
borderRightColor:'blue'
},
indicatorStyle : {
backgroundColor : 'red'
},
tabBarIcon: ({ focused, tintColor }) => {
const iconName = `bell-o`;
return <Icons name={iconName} size={27} color={tintColor} />;
},
}
}
You can get an idea from the below given code.
import Splash from '../Splash/Splash';
import Home from '../screens/Home';
import DrawerScreen from '../screens/DrawerScreen'
//And many more
import {createStackNavigator,
createSwitchNavigator,
createAppContainer,
createDrawerNavigator} from 'react-navigation';
const AppStack = createDrawerNavigator({
Home:Home,
},{
contentComponent: DrawerScreen,
defaultNavigationOptions: {
drawerWidth: Dimensions.get('window').width - 120,
},
});
const AppNavigator = createStackNavigator({
Splash:Splash,
Login:Login,
SignUp:SignUp },,{
defaultNavigationOptions: {
header: null,
gesturesEnabled: false
},
initialRouteName: "Splash");
const AppContainer = createAppContainer(AppNavigator);
Whenever you want to open the drawer like on click of the drawer icon. then add these line in the onPress definition.
this.props.navigation.openDrawer();

react-navigation : How to hide one specific tabBar icon and label

I am using react-navigation. I have three icons for my bottomtab navigator and I only want to show two icons(screen1 & screen2) and hide the other(screen3).
How can I hide the icon and the label of screen3?
This is my code:
const ButtomTabNavigator = createBottomTabNavigator(
{
screen1: {
screen: screen1,
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'screen1',
header: null,
tabBarIcon: ({ tintColor }) => (
<Image style={{ width: 18, height: 18, tintColor: tintColor }}
source={require('./Components/Assets/iconMyGrey.png')}
/>
),
})
},
screen2: {
screen: screen2,
navigationOptions: {
header: null,
tabBarLabel: 'screen2',
tabBarIcon: ({ tintColor }) => (
<Image style={{ width: 18, height: 18, tintColor: tintColor }}
source={require('./Components/Assets/iconListGrey.png')}
/>
),
}
},
screen3: {
screen: screen3,
navigationOptions: {
header: null,
tabBarLabel: 'screen3',
tabBarIcon: ({ tintColor }) => (
<Image style={{ width: 21, height: 17, tintColor: tintColor }}
source={require('./Components/Assets/iconReservationMint.png')}
/>
),
}
},
},
{
tabBarOptions: {
activeTintColor: '#16bb92',
},
shifting: true,
}
)
Any advice or comments would be really appreciated! Thanks in advance :)
Please try this
const HomeTab = createBottomTabNavigator(
{
Scree1: Screen1,
Screen2: Screen2,
Screen3: Screen3,
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === "Screen1") {
iconName = Images.icons.efficiencyTab;
} else if (routeName === "Screen2") {
iconName = Images.icons.messagesTab;
} else if (routeName === "Screen3") {
return (<View/>)
}
return (
<Image
style={{ width: 30, height: 30, tintColor: tintColor }}
source={iconName}
/>
);
},
tabBarLabel: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let title;
if (routeName === "Screen1") {
title = "Screen1";
} else if (routeName === "Screen2") {
title = "Screen2";
} else if (routeName === "Screen3") {
title = "";
}
return (
<Text
style={{
// alignSelf: "center",
textAlign: "center",
fontSize: 12,
color: tintColor,
marginBottom: 3
}}
>
{title}
</Text>
);
}
}),
tabBarOptions: {
activeTintColor: Constants.APP_THEME_COLOR2,
inactiveTintColor: Constants.APP_GRAY_COLOR,
style: {
height: 50
},
labelStyle: {
marginBottom: 3
}
}
}
);
You can remove screen3 from createBottomTabNavigator and add this screen to RootNavigator. If you want to navigate to screen3 you can navigation.navigate("screen3").In detail https://snack.expo.io/HytREN3ur.

this.props.navigation.navigate() is not working for AppDrawerNavigator

I'm facing issue in navigation in android app. When button is clicked app screen freezes, it does not redirect to next screen which is createDrawerNavigator() screen. Calling it from the Country selection screen.
import React, { Component } from "react";
import { View, Image, StyleSheet } from "react-native";
import AsyncStorage from "#react-native-community/async-storage";
import {
createSwitchNavigator,
createStackNavigator,
createDrawerNavigator,
createAppContainer
} from "react-navigation";
import CustomizedStatusBar from "./src/components/CustomizedStatusBar";
import Splash from "./src/screens/Splash";
import Login from "./src/screens/Login";
import CountrySelection from "./src/screens/CountrySelection";
import Dashboard from "./src/screens/Dashboard";
import ImportantNotice from "./src/screens/ImportantNotice";
import ApplicationForm from "./src/screens/ApplicationForm";
import ApplicationForm2 from "./src/screens/ApplicationForm2";
import ApplicationForm3 from "./src/screens/ApplicationForm3";
import ApplicationForm4 from "./src/screens/ApplicationForm4";
import Instructions from "./src/screens/Instructions";
import TravelHistory from "./src/screens/TravelHistory";
import TravelHistoryDetails from "./src/screens/TravelHistoryDetails";
import DownloadStamp from "./src/screens/DownloadStamp";
import LearnAbout from "./src/screens/LearnAbout";
import Advices from "./src/screens/Advices";
import TellAFriend from "./src/screens/TellAFriend";
import Contact from "./src/screens/Contact";
import SideMenu from "./src/screens/SideMenu";
import SignatureCapture from "./src/screens/SignatureCapture";
import CMS from "./src/screens/CMS";
import GLOBAL from "./src/config/constants";
import { Provider } from "react-redux";
import store from "./src/redux/store/index";
import NavigationDrawerStructure from "./src/components/NavigationDrawerStructure";
import NavigationService from "./src/config/NavigationService";
const CMSStackNavigator = createStackNavigator({
CMS: {
screen: CMS
}
});
const HomeStackNavigator = createStackNavigator({
Home: {
screen: Dashboard
}
});
const ApplicationFormStackNavigator = createStackNavigator({
ApplicationForm: {
screen: ApplicationForm,
navigationOptions: ({ navigation }) => ({
title: "",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const ApplicationForm2StackNavigator = createStackNavigator({
ApplicationForm2: {
screen: ApplicationForm2,
navigationOptions: ({ navigation }) => ({
title: "",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const ApplicationForm3StackNavigator = createStackNavigator({
ApplicationForm3: {
screen: ApplicationForm3,
navigationOptions: ({ navigation }) => ({
title: "",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const SignatureCaptureStackNavigator = createStackNavigator({
SignatureCapture: {
screen: SignatureCapture,
navigationOptions: ({ navigation }) => ({
title: "",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const ApplicationForm4StackNavigator = createStackNavigator({
ApplicationForm4: {
screen: ApplicationForm4,
navigationOptions: ({ navigation }) => ({
title: "",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const TravelHistoryStackNavigator = createStackNavigator({
TravelHistory: {
screen: TravelHistory
}
});
const TravelHistoryDetailsStackNavigator = createStackNavigator({
TravelHistoryDetails: {
screen: TravelHistoryDetails
}
});
const DownloadStampStackNavigator = createStackNavigator({
DownloadStamp: {
screen: DownloadStamp,
navigationOptions: ({ navigation }) => ({
title: "IMMIGRATION STAMP",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const TellAFriendStackNavigator = createStackNavigator({
TellAfriend: {
screen: TellAFriend,
navigationOptions: ({ navigation }) => ({
title: "TELL A FRIEND",
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: GLOBAL.COLOR.PRIMARY_COLOR
},
headerTintColor: GLOBAL.COLOR.HEADER_TINT_COLOR
})
}
});
const AppDrawerNavigator = createDrawerNavigator(
{
home: {
screen: HomeStackNavigator
},
application_form: {
screen: ApplicationFormStackNavigator,
navigationOptions: {
drawerLabel: "",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
application_form2: {
screen: ApplicationForm2StackNavigator,
navigationOptions: {
drawerLabel: "",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
application_form3: {
screen: ApplicationForm3StackNavigator,
navigationOptions: {
drawerLabel: "",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
signature_capture: {
screen: SignatureCaptureStackNavigator,
navigationOptions: {
drawerLabel: "",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
application_form4: {
screen: ApplicationForm4StackNavigator,
navigationOptions: {
drawerLabel: "",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
travel_history: {
screen: TravelHistoryStackNavigator
},
travel_history_details: { screen: TravelHistoryDetailsStackNavigator },
download_stamp: {
screen: DownloadStampStackNavigator,
navigationOptions: {
drawerLabel: "IMMIGRATION STAMP",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
tellafriend: {
screen: TellAFriendStackNavigator,
navigationOptions: {
drawerLabel: "TELL A FRIEND",
drawerIcon: ({ tintColot }) => (
<Image source={GLOBAL.MENU_ICON} style={{ width: 20, height: 20 }} />
)
}
},
cms: {
screen: CMSStackNavigator
}
},
{
contentComponent: SideMenu
}
);
export default class App extends Component {
constructor(props) {
super(props);
}
componentWillMount() {}
componentDidMount() {}
getPreferenceInfo = async () => {
const isLoggedIn = await AsyncStorage.getItem(
GLOBAL.PREFERENCE_STORAGE_KEY.IS_LOGGED_IN
);
const isLanguageSelected = await AsyncStorage.getItem(
GLOBAL.PREFERENCE_STORAGE_KEY.IS_LANGUAGE_SELECTED
);
return { isLoggedIn: isLoggedIn, isLanguageSelected: isLanguageSelected };
};
render() {
const AppSwitchNavigator = createSwitchNavigator(
{
SplashScreen: { screen: Splash },
LoginScreen: { screen: Login },
CountryScreen: { screen: CountrySelection },
DashboardScreen: { screen: AppDrawerNavigator }
},
{
initialRouteName: "AppScreen"
}
);
const AppContainer = createAppContainer(AppSwitchNavigator);
return (
<Provider store={store}>
<View style={{ flex: 1 }}>
<CustomizedStatusBar />
<AppContainer />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
bg: {
width: "100%",
height: "100%"
}
});
// Calling it from CountrySelection.js (CountryScreen)
import React, { Component } from "react";
import {
View,
Text,
StyleSheet,
Image,
Keyboard,
TouchableWithoutFeedback,
TouchableOpacity,
SafeAreaView,
KeyboardAvoidingView,
ActivityIndicator,
Alert
} from "react-native";
import AsyncStorage from "#react-native-community/async-storage";
import { StackActions, NavigationActions } from "react-navigation";
import CustomInputBox from "../components/CustomInputBox";
import GLOBAL from "../config/constants";
import { connect } from "react-redux";
import {
selectCountryWithIndex,
openCountrySelectionView,
getCountries,
openLanguageSelectionView
} from "../redux/actions/index";
import CountrySelectionPicker from "../components/CountrySelectionPicker";
import LanguageSelectionPicker from "../components/LanguageSelectionPicker";
class CountrySelection extends Component {
constructor(props) {
super(props);
this.didPressSubmit = this.didPressSubmit.bind(this);
this.navigateAfterFinish = this.navigateAfterFinish.bind(this);
this.state = {
isLoading: true,
animating: false,
selectedCountry: null,
stores: []
};
}
static navigationOptions = {
header: null
};
navigateAfterFinish = screen => {
const resetAction = StackActions.reset({
actions: [NavigationActions.navigate({ routeName: "DashboardScreen" })]
});
this.props.navigation.dispatch(resetAction);
};
getSelectedCountryInfo = async () => {
try {
let value = await AsyncStorage.getItem(
GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY
);
let selectedIndex = await AsyncStorage.getItem(
GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_INDEX
);
return { selectedCountry: value, selectedIndex: selectedIndex };
} catch (e) {
console.log(e);
}
};
onSelectLanguage = async (langCode, langId) => {
// Alert.alert(
// "Error",
// langCode + "==" + langId,
// [
// {
// text: "OK"
// }
// ],
// { cancelable: false }
// );
try {
await AsyncStorage.setItem(
GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY,
JSON.stringify(this.props.countrySelectionReducers.selectedCountry)
);
await AsyncStorage.setItem(
GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_LANGUAGE_CODE,
langCode
);
await AsyncStorage.setItem(
GLOBAL.PREFERENCE_STORAGE_KEY.SELECTED_COUNTRY_LANGUAGE_CODE_ID,
langId
);
await AsyncStorage.setItem(
GLOBAL.PREFERENCE_STORAGE_KEY.IS_LANGUAGE_SELECTED,
"true"
);
return true;
} catch (e) {
// Alert.alert(
// "Error",
// e,
// [
// {
// text: "OK"
// }
// ],
// { cancelable: false }
// );
console.log(e);
return false;
}
};
getAllDatas = () => {
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (err, stores) => {
this.setState({ stores });
});
});
};
didPressSubmit = () => {
this.props.navigation.navigate("DashboardScreen");
};
componentWillMount() {}
componentDidMount() {
this.props.getCountries();
this.getAllDatas();
// this.getSelectedCountryInfo().then(data => {
// this.props.selectCountryWithIndex(
// JSON.parse(data.selectedCountry),
// parseInt(data.selectedIndex)
// );
// });
}
render() {
const { navigate } = this.props.navigation;
return (
<KeyboardAvoidingView behavior={"padding"} style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1 }}>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}
>
<View style={styles.container}>
<Image style={styles.bg} source={GLOBAL.LOGIN_BGIMG} />
<View style={styles.formContainer}>
<Text style={styles.textContainer}>
{GLOBAL.SELECT_COUNTRY}
</Text>
<View style={{ flex: 1 }}>
<CustomInputBox
icon={
this.props.countrySelectionReducers.selectedCountry !==
null
? {
uri: this.props.countrySelectionReducers
.selectedCountry.country_logo
}
: null
}
leftInputIconStyle={
this.props.countrySelectionReducers.selectedCountry !==
null
? {
width: 32,
height: 20,
borderWidth: 0.5,
borderColor: "#c6c6c6"
}
: null
}
keyboardType="default"
returnKeyType="next"
showPlaceholder={false}
_placeholder={GLOBAL.COUNTRY_PLACEHOLDER}
showRightIcon={true}
rightIcon={GLOBAL.COUNTRY_RIGHT_ICON}
defaultValue={
this.props.countrySelectionReducers.selectedCountry !==
null
? this.props.countrySelectionReducers.selectedCountry
.country_name
: null
}
/>
<TouchableOpacity
style={{
backgroundColor: "transparent",
top: 0,
bottom: 0,
left: 0,
right: 0,
position: "absolute"
}}
onPress={() => this.props.openCountrySelectionView()}
/>
</View>
<View style={{ flex: 1 }}>
<CustomInputBox
icon={
this.props.countrySelectionReducers.selectedLanguage !==
null
? {
uri:
GLOBAL.URL.uploads +
this.props.countrySelectionReducers
.selectedLanguage.language_code +
".png"
}
: null
}
leftInputIconStyle={
this.props.countrySelectionReducers.selectedLanguage !==
null
? {
width: 32,
height: 20,
borderWidth: 0,
borderColor: "#c6c6c6"
}
: null
}
keyboardType="default"
returnKeyType="done"
showPlaceholder={false}
_placeholder={GLOBAL.LANGUAGE_PLACEHOLDER}
showRightIcon={true}
rightIcon={GLOBAL.COUNTRY_RIGHT_ICON}
customStyle={{ marginTop: 20 }}
defaultValue={
this.props.countrySelectionReducers.selectedLanguage !==
null
? this.props.countrySelectionReducers.selectedLanguage
.language_name
: null
}
/>
<TouchableOpacity
style={{
backgroundColor: "transparent",
top: 0,
bottom: 0,
left: 0,
right: 0,
position: "absolute"
}}
onPress={() => this.props.openLanguageSelectionView()}
/>
</View>
<TouchableOpacity
style={[styles.btn, { marginTop: 30 }]}
onPress={() => this.didPressSubmit()}
>
<Image
style={styles.btnImg}
resizeMode="contain"
source={GLOBAL.BTN_BGIMG}
/>
<View style={styles.btnContainer}>
<Text style={styles.btnText}>{GLOBAL.LOGINBTN}</Text>
</View>
</TouchableOpacity>
</View>
{this.props.countrySelectionReducers.isAnimating ? (
<View
style={{
width: "100%",
height: "100%",
position: "absolute",
justifyContent: "center",
alignItems: "center"
}}
>
<View
style={{
flex: 1,
backgroundColor: "#000000",
width: "100%",
height: "100%"
}}
opacity={0.6}
/>
<ActivityIndicator
style={{ alignSelf: "center", position: "absolute" }}
size="large"
color="#ffffff"
/>
</View>
) : null}
</View>
</TouchableWithoutFeedback>
<CountrySelectionPicker />
<LanguageSelectionPicker />
</SafeAreaView>
</View>
</KeyboardAvoidingView>
);
}
}
const mapStateToProps = state => {
return {
countrySelectionReducers: state.CountrySelectionReducers
};
};
export default connect(
mapStateToProps,
{
selectCountryWithIndex,
openCountrySelectionView,
getCountries,
openLanguageSelectionView
}
)(CountrySelection);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
bg: {
width: "100%",
height: "100%"
},
formContainer: {
position: "absolute",
width: "100%",
paddingHorizontal: 30,
flexGrow: 1
},
textContainer: {
fontSize: 20,
fontWeight: "bold",
color: "#ffffff",
alignSelf: "center",
textAlign: "center",
marginBottom: 30
},
btn: {
alignItems: "center",
justifyContent: "center"
},
btnText: {
fontSize: 20,
fontWeight: "bold",
color: "#ffffff",
alignSelf: "center"
},
btnContainer: {
alignItems: "center",
justifyContent: "center",
position: "absolute"
},
btnImg: {
resizeMode: "contain",
left: 0,
right: 0,
top: 0,
bottom: 0,
height: 46
}
});
Wanted to redirect user to DashboardScreen from CountryScreen using this.props.navigation.navigate("DashboardScreen"). But it fails. No error is thrown.
This has been resolved. The issue was with hybrid-crypto-js library. It was throwing an exception due to which navigation stops.

Header is empty after react-navigation updated to v2

After updating react-navigation package of my react-native project from 1.5.8 to 2.0.1 my header became empty on all tabs of TabNavigator. On other screens it works as before.
Example of tab Dashboard:
class Dashboard extends PureComponent {
static navigationOptions = ({ navigation }) => {
return {
title: strings.dashboard_header_title,
headerLeft: renderMenu(navigation)
};
};
...
}
export default connect((state, ownProps) => {
...
})(Dashboard);
const renderMenu = navigation => {
return <ImageButton
style={styles.padding}
imageStyle={styles.tintWhite}
image={require('../../../res/images/menu.png')}
onPress={navigation.state.params && navigation.state.params.toggleSideMenu}/>
}
It worked with old version of react-navigation. I use react-redux and tab navigator inside stack navigator.
TabNavigator:
const routeConfig = {
Dashboard: {
screen: Dashboard,
resource: 'dashboard',
navigationOptions: { tabBarIcon: ({tintColor}) => <Image style={{tintColor}} source={require('../../../res/images/tab-dashboard.png')}/> }
},
...
};
const drawConfig = {
lazy: false,
animationEnabled: false,
swipeEnabled: false,
tabBarPosition: 'bottom',
tabBarOptions: {
upperCaseLabel: false,
activeBackgroundColor: 'white',
activeTintColor: colors.main,
inactiveTintColor: colors.normal,
showIcon: true,
style: {
height: 48,
backgroundColor: 'white',
borderTopColor: colors.border,
borderTopWidth: values.borderWidth,
elevation: 0
},
labelStyle: {
fontSize: 11,
marginBottom: 0
},
tabStyle: {
padding: 3,
paddingTop: Platform.OS === 'android' ? 4 : 3
},
indicatorStyle: {
height: 0,
width: 0
}
}
}
const InnerTabNavigator = createBottomTabNavigator(routeConfig, drawConfig);
class TabBarNavigator extends PureComponent
{
...
render() {
return (
<InnerTabNavigator
{...this.props.ownProps}
navigation={{
...this.props.navigation,
state: this.state
}}
/>
);
}
...
}
TabBarNavigator.router = InnerTabNavigator.router;
MainNavigator:
const MainNavigatorInner = createStackNavigator({
...
TabBarNavigator: { screen: TabBarNavigator },
...
}, {
initialRouteName: 'SignIn',
headerMode: 'screen',
navigationOptions: ({ navigation }) => {
return {
headerTintColor: 'white',
headerTitleStyle: styles.headerTitle,
headerStyle: {
backgroundColor: colors.main,
shadowColor: 'transparent',
elevation: 0,
borderBottomWidth: values.borderWidth,
borderBottomColor: colors.borderHeader,
height: values.headerHeight
},
};
},
cardStyle: {
backgroundColor: colors.background
}
});
export default class MainNavigator extends PureComponent {
...
render() {
return (
...
<MainNavigatorInner
ref='navigation'
screenProps={this.screenProps}
onNavigationStateChange={this._onNavigationStateChange}/>
...
);
}
...
}
I had the same issue yesterday when I updated my react-navigation too. I know that this is not optimal but try adding the tabBarIcon in your drawconfig:
const drawConfig = {
lazy: false,
animationEnabled: false,
swipeEnabled: false,
tabBarPosition: 'bottom',
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let icon;
if (routeName === "SomeRouteName") {
icon = require("src/assets/someFile");
} else if (routeName === "Some other route name") {
if (focused) {
icon = require("src/assets/someFile.png");
} else {
icon = require("src/assets/someFile.png");
}
}
return <Image source={icon} style={{ width: 30, height: 30 }} />;
}
}),
tabBarOptions: {
upperCaseLabel: false,
activeBackgroundColor: 'white',
activeTintColor: colors.main,
inactiveTintColor: colors.normal,
showIcon: true,
style: {
height: 48,
backgroundColor: 'white',
borderTopColor: colors.border,
borderTopWidth: values.borderWidth,
elevation: 0
},
labelStyle: {
fontSize: 11,
marginBottom: 0
},
tabStyle: {
padding: 3,
paddingTop: Platform.OS === 'android' ? 4 : 3
},
indicatorStyle: {
height: 0,
width: 0
}
}
}
I had same ıssue too my solution is added my stacknavigator
headerMode: 'auto' property, I using expo template and RootNavigation file is added headerMode: 'auto' too, it worked for me,
Roote navigation like this =>
const RootStackNavigator = createStackNavigator(
{
Main: {
screen: MainTabNavigator,
},
},
{
navigationOptions: () => ({
headerTitleStyle: {
fontWeight: 'normal',
},
}),
headerMode: 'auto'
}
);

React Native - Change background color in tabnavigator dynamically

i want to change my tab navigator background color dynamically in based on my API response so below is my code
_TabNavigator.js
const MyTabnav = TabNavigator({
ScreenOne: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenOne</Text>
</View>
)
}
},
ScreenTwo: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps, }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenTwo</Text>
</View>
)
}
},
ScreenThree: {
screen: ({ navigation, screenProps }) => <StockNotificationNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenThree</Text>
</View>
)
}
},
},
{
tabBarOptions: {
style: {
backgroundColor: white,
height: 55,
borderTopColor: 'transparent',
borderTopWidth: 1,
paddingRight: 10,
paddingLeft: 10,
borderTopWidth: 1,
borderTopColor: grayPlaceHolder
},
showLabel: false,
showIcon : true,
},
tabBarComponent : TabBarBottom,
initialRouteName: 'ScreenTwo',
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}, []);
var styles = StyleSheet.create({
tabText: {
fontSize: 10,
fontWeight: "600",
flex: 4,
},
tabViewBox: {
flex: 1,
alignItems: "center",
},
tabIcon: {
flex: 5,
alignSelf: "center",
marginTop: 10
},
});
export default StocksTabNav;
I want to change my tabnavigtor background color in my ScreenTwo.js file which include API response code on it as per that it tabnavigator background color (backgroundColor) should change as black or white as per API response so how can i achieve this? your all suggestions are appreciable
After update code as per Rahul suggests give below warning message
what you can do is make one custom tabBar component and using javaScript immutability concept you can override style of tabBarOptions.
const MyTabnav = TabNavigator({ScreenOne: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenOne</Text>
</View>
)
}
},
ScreenTwo: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps, }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenTwo</Text>
</View>
)
}
},
ScreenThree: {
screen: ({ navigation, screenProps }) => <StockNotificationNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenThree</Text>
</View>
)
}
},
},
{
tabBarOptions: {
style: {
backgroundColor: white,
height: 55,
borderTopColor: 'transparent',
borderTopWidth: 1,
paddingRight: 10,
paddingLeft: 10,
borderTopWidth: 1,
borderTopColor: grayPlaceHolder
},
showLabel: false,
showIcon : true,
},
//Here Goes Your CustomTabBar Component
tabBarComponent : CustomTabBarComponent,
initialRouteName: 'ScreenTwo',
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}, []);
CustomTabBarComponent.js
const TabBar = (props) => {
const { navigationState } = props;
let newProps = props;
newProps = Object.assign(
{},
props,
{
style: {
// get value from redux store and set it here
backgroundColor: 'rgba(0,0,0,0.1)',
position: 'absolute',
bottom: 0,
left: 0,
right: 0
},
activeTintColor: '#fff',
inactiveTintColor: '#bbb',
},
);
return <TabBarBottom {...newProps} />;
};
Now You can connect this CustomTabBarComponent with Redux store and can change the value of whatever Property you want.
What you need to do is set your tab component as a function and send the color as a parameter to that function. Try this:
const MyTabnav = color => TabNavigator({
ScreenOne: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenOne</Text>
</View>
)
}
},
ScreenTwo: {
screen: ({ navigation, screenProps }) => <ScreenOneNav screenProps={{ tabbarNavigation: navigation, ...screenProps, }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'ScreenOne',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenTwo</Text>
</View>
)
}
},
ScreenThree: {
screen: ({ navigation, screenProps }) => <StockNotificationNav screenProps={{ tabbarNavigation: navigation, ...screenProps }} onNavigationStateChange={null} />,
navigationOptions: {
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (
<View style={[styles.tabViewBox]}>
<Text style={[styles.tabText, { color: tintColor }]}>ScreenThree</Text>
</View>
)
}
},
},
{
tabBarOptions: {
//use the color you passed in the prop here:
style: {
backgroundColor: color,
height: 55,
borderTopColor: 'transparent',
borderTopWidth: 1,
paddingRight: 10,
paddingLeft: 10,
borderTopWidth: 1,
borderTopColor: grayPlaceHolder
},
showLabel: false,
showIcon : true,
},
tabBarComponent : TabBarBottom,
initialRouteName: 'ScreenTwo',
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}, []);
var styles = StyleSheet.create({
tabText: {
fontSize: 10,
fontWeight: "600",
flex: 4,
},
tabViewBox: {
flex: 1,
alignItems: "center",
},
tabIcon: {
flex: 5,
alignSelf: "center",
marginTop: 10
},
});
export default MyTabNav;
Then where you use MyTabnav pass the color as a param to it. for example
export default class App extends Component<{}> {
constructor(props) {
super(props);
this.state = {
color: 'black'
};
}
getRandomColor = () => {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
onPress = () => {
this.setState({
color: this.getRandomColor()
});
};
render() {
const Tabs = MyTabnav(this.state.color);
return (
<View style={{ flex: 1 }}>
<Button onPress={this.onPress} title="Click me" />
<Tabs />
</View>
);
}
}
try using
const tabBarOptions = {
// setting height 'null', and top 0 will change the color of pressed tab
indicatorStyle: {
height: null,
top: 0,
backgroundColor: "red",
borderBottomColor: "black",
borderBottomWidth: 3,
},
activeTintColor: "black",
pressColor: "white",
style: {
backgroundColor: "#ddc8be",
},
labelStyle: { fontSize: 13 },
};