Ripple Effect on BottomTabNavigator - react-native

I'm trying to add Ripple Effect like this in BottomTabNavigator but don't know how?
I'm using createMaterialBottomTabNavigator for BottomTabNavigator.

To get the Material Bottom Tab Navigator to change color you need to use the tabBarColor property of the navigationOptions for each tab. You can see this in the documentation here. You also need to set shifting to be true in the navigator's config if you want the ripple effect.
You will need to make sure that you have the following dependencies installed:
react-navigation
react-navigation-material-bottom-tabs
react-native-paper
react-native-vector-icons, though if using Expo this is not required as it is already included
For more details on the dependencies that you need see the documentation
Here is a sample navigator:
import * as React from 'react';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import { createAppContainer } from 'react-navigation';
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'; // <- notice where we import createMaterialBottomTabNavigator from
import { MaterialIcons } from '#expo/vector-icons';
const tabBarIcon = name => ({ tintColor }) => (
<MaterialIcons
style={{ backgroundColor: 'transparent' }}
name={name}
color={tintColor}
size={24}
/>
);
const screens = {
Screen1: {
screen: Screen1,
navigationOptions: {
tabBarIcon: tabBarIcon('photo-album'),
tabBarColor: 'blue' // <- set this to the color you want
}
},
Screen2: {
screen: Screen2,
navigationOptions: {
tabBarIcon: tabBarIcon('favorite'),
tabBarColor: 'green' // <- set this to the color you want
}
}
};
const config = {
headerMode: 'none',
initialRouteName: 'Screen1',
shifting: true, // <- notice this has been set to true
activeColor: 'white',
inactiveColor: 'black'
};
const MainNavigator = createMaterialBottomTabNavigator(screens, config);
export default createAppContainer(MainNavigator);
I would have created a snack to show this working but unfortunately react-navigation-material-bottom-tabs doesn't play nice in a snack, but it does play nice in a local Expo or react-native app.

Related

Unable to add an Icon to Bottom Tab Bar with Nested Stack Navigator

I have this Navigator which I'm trying to add 1 Icon and changing the background color of the Tab bar (if possible of the icons and Labels.
import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { BottomTabBar, createBottomTabNavigator } from 'react-navigation-tabs';
import AccountScreen from './src/screens/AccountScreen';
import SigninScreen from './src/screens/SigninScreen';
import SignupScreen from './src/screens/SignupScreen';
import TrackCreateScreen from './src/screens/TrackCreateScreen';
import TrackListScreen from './src/screens/TrackListScreen';
import TrackDetailScreen from './src/screens/TrackDetailScreen';
import { Provider as AuthProvider } from './src/context/AuthContext';
import {setNavigator} from './src/navigationRef';
import ResolveAuthScreen from './src/screens/ResolveAuthScreen';
import Icon from 'react-native-vector-icons/Ionicons';
const switchNavigator = createSwitchNavigator({
ResolveAuth: ResolveAuthScreen,
loginFlow: createStackNavigator({
Signin: SigninScreen,
Signup: SignupScreen,
}),
mainFlow: createBottomTabNavigator({
trackListFlow: createStackNavigator({
TrackList: TrackListScreen,
TrackDetail: TrackDetailScreen,
}),
TrackCreate: {
screen: TrackCreateScreen,
navigationOptions:{
tabBarLabel: 'Crear Track',
tabBarIcon: ({tintColor})=>(
<Icon name="ios-analytics" color={tintColor} size={25}/>
)
}
},
Account: {
screen: AccountScreen,
navigationOptions:{
tabBarLabel: 'Cuenta',
tabBarIcon: ({tintColor})=>(
<Icon name="ios-person" color={tintColor} size={25}/>
)
}
},
})
});
const App = createAppContainer(switchNavigator);
export default () => {
return (
<AuthProvider>
<App ref={(navigator) => {setNavigator(navigator)}}/>
</AuthProvider>
);
};
For just the tabs there was no issue but having a Tab that has the Nested Stack Navigator doesn't allow me to set up an Icon and a Label.
And I can't find any info or a way to add a background color to this Tab.
Any ideas?
Kind Regards.
This happen because you did not provide icon to the first tab. Please update tasklistflow with the following block
trackListFlow: {
screen: createStackNavigator({
TrackList: TrackListScreen,
TrackDetail: TrackDetailScreen,
}),
navigationOptions:{
tabBarLabel: 'Task List Flow',
tabBarIcon: ({tintColor})=>(
<Icon name="ios-analytics" color={tintColor} size={25}/>
)
}
},

Single screen application without bottom navigation bar

I've analyzed the needs of my application and decided I can more efficiently develop it with mobile friendly components on the web and present it via a web view in an app.
I need permissions to access camera and gallery (to take photos / videos, and upload photos / videos).
Basically, a single-screen app with a webview presenting the site with mobile-friendly components and the above permissions.
This is my current app.js:
import React from 'react';
import { Button, Text, View, TouchableOpacity, StyleSheet } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';
import {
createStackNavigator,
createBottomTabNavigator,
createAppContainer,
} from 'react-navigation';
//import createStackNavigator, createBottomTabNavigator, createAppContainer in our project
import HomeScreen from './pages/HomeScreen';
import { Constants, Location, Camera, Permissions } from 'expo';
const ProfileStack = createStackNavigator(
{
//Definition of Navigaton from home screen
HomeScreen: { screen: HomeScreen },
},
{
//For React Navigation 2.+ change defaultNavigationOptions->navigationOptions
defaultNavigationOptions: {
//Header customization of the perticular Screen
headerStyle: {
backgroundColor: 'orange',
},
headerTintColor: '#FFFFFF',
title: '',
//Header title
},
}
);
const App = createBottomTabNavigator(
{
HomeScreen: { screen: HomeScreen },
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let IconComponent = Ionicons;
let iconName;
if (routeName === 'HomeScreen') {
iconName = `ios-information-circle${focused ? '' : '-outline'}`;
}
return <IconComponent name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'orange',
inactiveTintColor: 'gray',
},
}
);
export default createAppContainer(App);
and './pages/HomeScreen':
//This is an example code for Bottom Navigation//
import React, {Component} from 'react';
//import react in our code.
import { Text, View, TouchableOpacity, StyleSheet, WebView } from 'react-native';
//import all the basic component we have used
export default class ProfileScreen extends React.Component {
//Profile Screen to show from Open profile button
render() {
return (
<WebView
source={{uri: 'https://mobilesite'}}
style={{marginTop: 20}}
/>
);
}
}
So far, the site opens on a single screen as expected, but there's a bottom navigation bar present; I'd also like to preferably hide the top bar if possible too as I've accounted for that in a mobile-friendly header on the mobile site as well.
Also, via the mobile web codebase, I'm utilizing <input type="file" /> for uploading. Is this compatible with React Native Permissions?
You're using createBottomTabNavigator() and passing the resulting navigator to your createAppContainer() which will create a bottom tab navigator.
If you pass a StackNavigator (via createStackNavigator() which you use for ProfileStack) to the createAppContainer() it'll render the stack as opposed to the bottom tab navigator which is what you want.
To remove the header altogether you can use headerMode: 'none' in the navigationOptions param.
You can see a basic version of what you want here (sans the lack of a header) in the React Navigation docs.

react native vector icons showing X instead of icon

I cant seem to figure this out. I can get something to show, but its a box with an X in it, so im assuming its not picking up the vector icons. Any advice?
I have the show icon true, I have the tint color, I have the vector icons (i have tried both ionicons and font awesome, to no avail.
Code:
import React, { Component} from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-
navigation';
import Icon from 'react-native-vector-icons/FontAwesome';
class HomeScreen extends Component {
static navigationOptions = {
title: 'Home'
};
render(){
return (
<View style={{ flex:1, alignItems:'center', justifyContent:'center'
}}>
<Text>Home Screen</Text>
</View>
);
}
}
const RootStack = createBottomTabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor }) => (
<Icon name = 'home' size={25} color={tintColor} />
)
}
},
},
{
tabBarOptions: {
showIcon:true,
tintColor:'red'
}
}
);
const AppContainer = createAppContainer(RootStack);
const styles = StyleSheet.create({
})
export default class App extends Component{
render(){
return <AppContainer />;
}
}
I am using react-native version 0.62 and I encountered this error too. Though 0.60+ versions of react native provide auto-linking feature, but for react-native-vector-icons this is an exception. You need to link it manually. To solve it, follow below steps
rm -rf node_modules
yarn
yarn react-native link
Hope that helps.
Fixed this. Once i realized it was the vectors, i just linked react-native with react-native-vectors.

How to add React-Navigation Drawer menu to my screens?

I have a home screen built with React-Navigation 3.x. I have a header, some navigation icons, and a bottom tab menu. It is working well, but now I want to add a drawer menu to the screen and add an icon at the top right corner to toggle the drawer.
Here's a simplified version of my home screen (App.js):
import { createStackNavigator, createAppContainer, createBottomTabNavigator } from 'react-navigation';
import Activity1 from './Activity/Activity1';
import Activity2 from './Activity/Activity2';
import Activity3 from './Activity/Activity3';
import Calendar from './Screens/Calendar';
import Graph from './Screens/Graph';
import DrawerMenu from './components/DrawerMenu';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerRight: (<Button onPress={() => this.props.navigation.toggleDrawer()} title='Menu' />)
};
render() {
return (
<View style={styles.container}>
<View style={styles.iconContainer}>
<Icon name='icon1' onPress={this.navToActivity1} />
<Icon name='icon2' onPress={this.navToActivity2} />
<Icon name='icon3' onPress={this.navToActivity3} />
</View>
<View>
<DrawerMenu />
</View>
</View>
);
}
}
//create my main navigation stacks here
const Home = createStackNavigator({
HomeScreen,
Activity1,
Activity2,
Activity3,
});
//The following two are for the bottom tab bar only
const Calendar = createStackNavigator({ Calendar });
const Graph = createStackNavigator({ Graph });
const BottomTabNav = createBottomTabNavigator({
Home, Calendar, Graph
});
export default createAppContainer(TabNavigator);
And here's the code for DrawerMenu.js
import { Dimensions } from 'react-native';
import { createDrawerNavigator, createAppContainer } from 'react-navigation';
import Settings from './Settings';
import Profile from './Profile';
const SCREENWIDTH = Dimensions.get('window').width;
const DrawerConfig = {
drawerWidth: SCREENWIDTH * 0.5,
drawerPosition: 'right',
};
const DrawerMenu = createDrawerNavigator({
Settings: { screen: Settings },
Profile: { screen: Profile },
},
DrawerConfig
);
export default createAppContainer(DrawerMenu);
I couldn't get the drawer to work. When I click on the "Menu" button at the top right corner in the Home Screen to invoke toggleDrawer(), I got an "undefined is not an object (evaluating 'ae.props.navigation')" error.
The drawer cannot be activated using gesture either, so I think I am not adding it correctly. What did I do wrong here? Thanks!!
install the package the react-native-drawer
https://www.npmjs.com/package/react-native-drawer
<Drawer
type="overlay"
ref={ref => (this._drawer = ref)}
content={<Sidebar />}
tapToClose={true}
openDrawerOffset={0.2} // 20% gap on the right side of drawer
panCloseMask={0.2}
closedDrawerOffset={-3}
styles={drawerStyles}
tweenHandler={ratio => ({ main: { opacity: (2 - ratio) / 2 } })}
>
cds

Dynamically change header title in react native navigation

For a school assignment we're creating an app in react native with react navigation and redux. Because all of us are new to react we have an issue we are unable to resolve.
We want to change the title of the header when a certain button is clicked. The first time we click a button it changes the header title just fine. The problem arrises when we press a different button, the header doesn't change. Note that no matter what option we choose, we always go to the same screen.
import React from 'react';
import { createStackNavigator, createAppContainer, createDrawerNavigator } from 'react-navigation';
import {connect} from 'react-redux';
import { store } from '#redux/MyStore';
import { Ionicons } from '#expo/vector-icons';
import ScannerScreen from '#screens/ContactScreen';
import EventsScreen from '#screens/ListScreen';
const ContactStack = createStackNavigator({
Contact: {
screen: ContactScreen,
navigationOptions: ({navigation}) => ({
headerStyle: {backgroundColor: '#fa8231'},
headerTitleStyle: {fontSize: 18},
title: store.getState().setupState.title,
headerLeft: <Ionicons
name="md-menu" style={{marginLeft:10}}
size={28}
onPress={() => navigation.toggleDrawer()} /> //menu button
})
}
});
// Code to create stack for the ListStack
const DrawerStack = createDrawerNavigator({
Contact: ContactStack,
List: ListStack
});
const PrimaryNavigation = createStackNavigator({
ListStack: {
screen: ListStack,
navigationOptions: {
header: null,
},
},
DrawerStack: {
screen: DrawerStack,
navigationOptions: {
header: null,
},
},
},
{
initialRouteName: 'ListStack',
});
const AppContainer = createAppContainer(PrimaryNavigation);
class AppNavigation extends React.Component {
render() {
return <AppContainer/>
}
}
export default (AppNavigation)
We did get it working when we put the title bar in the DrawerNavigator, but since we want the Drawer in from of the header that is not an option. My speculation is that the stack is created once with a certain title and never gets updated when switching screens using the DrawerNavigator but we have no clue how to fix that.
Thanks in advance!
From what I understand you need to change the title when a screen is loaded in stack.So you could use some like:
class ScreenInContactStack extends React.Component{
//Constryctor
static navigationOptions = ({navigation}) => ({
title: (navigation.state.params || {}).title || 'Chat! ',
});
//Remaining Logic
}
and while calling
this.props.navigation.navigate('ScreenInContactStack', {title: yourTitle + ' ',});
Don't know why but the Appbar condense the title to like yourTi.. to avoid this add a space to the title.
Try this:
map title as a prop to force ContactStack to re-render whenever it changes
class ContactStack extends React.Component {
render() {
const { title } = this.props.setupState;
const Stack = createStackNavigator({
Contact: {
screen: ContactScreen,
navigationOptions: ({navigation}) => ({
headerStyle: {backgroundColor: '#fa8231'},
headerTitleStyle: {fontSize: 18},
title,
headerLeft: <Ionicons
name="md-menu" style={{marginLeft:10}}
size={28}
onPress={() => navigation.toggleDrawer()} /> //menu button
})
}
});
return <Stack />;
}
}
const mapStateToProps = ({ setupState }) => ({setupState});
export default connect(mapStateToProps)(ContactStack);