align navscreen content in react-native - javascript

I am very new to react-native. I am trying to create a drawer using react-navigation. I could use DrawerNavigator but could not show the header/navbar on all the screens. That is why i create a NavScreen component with profile icon, title and back icon. However they are not aligned properly. I need profile icon to be shown on the left side, title on the center and back button on the right side. How can i do this?
Here is my code
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'ios' ? 20 : 10,
},
});
const NavScreen = ({ navigation, banner }) => (
<ScrollView style={styles.container}>
<Text>{banner}</Text>
<Icon
name="ios-contact-outline"
size={30}
color="#000"
onPress={() => navigation.navigate('DrawerOpen')}
/>
<Icon
name="ios-arrow-round-back-outline"
size={30}
color="#000"
onPress={() => navigation.goBack(null)}
/>
</ScrollView>
);
export default NavScreen;
class App extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.routeName}`,
drawerTitle: `${navigation.state.routeName}`,
drawerLabel: 'Home',
drawerIcon: ({ whiteColor }) => (
<MaterialIcons name="drafts" size={14} style={{ color: whiteColor }} />
),
})
render() {
const { navigation } = this.props;
return (
<ScrollView>
<NavScreen navigation={navigation} banner={'Main'} />
<Text>Main Screen</Text>
</ScrollView>
);
}
}
export default App;
I need similar to the below image

First, try to build a StackNavigation, at headerRight, and headerLeft you define your custom buttons (the above), now you can very easy customize the align/padding whatever you need with your icons/buttons.
const stackNavigatorConfiguration = {
// set first Screen
initialRouteName: 'Home',
mode: Platform.OS === 'ios' ? 'card' : 'card',
navigationOptions: ({navigation}) => ({
headerRight: <DrawerButton navigation={navigation} />,
headerLeft: <YourProfileButton navigation={navigation} />,
headerBackTitle: null
})
}
const YourProfileButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.profileButton}
name='ios-menu-outline'
size={32}
onPress={() => navigation.goBack(null)}
/>
</TouchableOpacity>
)
const DrawerButton = ({ navigation }) => (
<TouchableOpacity>
<Ionicons
style={styles.drawerIcon}
name='ios-menu-outline'
size={32}
onPress={() => navigation.navigate('DrawerOpen')}
/>
</TouchableOpacity>
)

Related

React native - No Icons on bottom menu

I'm trying to create a bottom menù flow, but I don't understand how and where I need to set the Icons of the bottom menù
At the moment I have setted the menù, it works and I'm able to personalize the menù names, but not able to set the icons. I start with the navigationOptions and before I changed the class in an extention of a component it works.
The following code is in my App.js File
const switchNavigator = createSwitchNavigator({
loginFlow: createStackNavigator({
Signin: SigninScreen,
Signup: SignupScreen
}),
mainFlow: createBottomTabNavigator({
/*Spogliatoio: createStackNavigator({
Game: GameScreen,
}),*/
Rosa: createStackNavigator({
Team: TeamScreen,
PlayerDetail: PlayerDetailScreen,
}),
Classifica: createStackNavigator({
LeagueTable: LeagueTableScreen,
}),
Calendario: createStackNavigator({
LeagueCalendar: LeagueCalendarScreen,
}),
/*Carriera: createStackNavigator({
Trainer: TrainerScreen,
}),*/
}),
});
const App = createAppContainer(switchNavigator);
export default () => {
return (
<AuthProvider>
<App ref={(navigator) => {setNavigator(navigator)}}/>
</AuthProvider>
);
};
And one of the class of my menu view is the following
export default class LeagueTableScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
nomeSquadra:''
}
}
componentDidMount() {
this.fetchData()
.catch((error) => {
//console.log(`Error: ${error}`)
});
}
render() {
const { state, navigate } = this.props.navigation;
const teamName = this.state.nomeSquadra;
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator/>
</View>
)
} else {
return (
<>
<SafeAreaView style={styles.container}>
<View style={styles.listItem}>
<Text style={styles.itemTeamName}>Nome Squadra</Text>
<Text style={styles.itemLegueDetail}>PG</Text>
<Text style={styles.itemLegueDetail}>V</Text>
<Text style={styles.itemLegueDetail}>P</Text>
<Text style={styles.itemLegueDetail}>S</Text>
<Text style={styles.itemLegueDetail}>+/-</Text>
<Text style={styles.itemLegueDetail}>RF</Text>
<Text style={styles.itemLegueDetail}>RS</Text>
<Text style={styles.itemLegueDetail}>PT</Text>
</View>
<FlatList style={styles.flatl}
data={this.state.dataSource}
keyExtractor={(item) => item.idSquadra}
renderItem={({item}) => {
return(
<TouchableOpacity >
<LegueViewItem item={item} nomeSquadra={teamName}/>
</TouchableOpacity>
)
}}
/>
</SafeAreaView>
</>
)
}
}
}
LeagueTableScreen['navigationOptions'] = () => ({
title: 'Classifica',
tabBarIcon: <SimpleLineIcons name="people" size={18} />
})
Can someone help me to set the icons on the bottom menu?
Thank you a lot in advance!
I finally found the answer ^^
createStackNavigator gives you a stackConfig option and there you can implement your NavigationOprions. So I only need to define my createStackNavigator with the following structure
Rosa: createStackNavigator({
Team: TeamScreen,
PlayerDetail: PlayerDetailScreen,
}, {navigationOptions: {tabBarIcon: <SimpleLineIcons name="people" size={18} />}
}),
I hope this can help some new developer that are experimenting React-Native :D

React Native: How to dispatch redux action from Custom Drawer

I have to dispatch logoutUser() action from CustomDrawerContentComponent. How can I do that?
I have a StackNavigator as well as Drawer Navigator in my app.
Also there is a CustomDrawerComponent to show the username of authenticated user as well as a sign up button in Drawer. Since it is outside the class, I'm unable to dispatch using props.
MainComponent.js
...other import statements
import {
fetchDishes,
fetchComments,
fetchPromos,
fetchLeaders,
logoutUser,
} from "../redux/ActionCreators";
const mapDispatchToProps = (dispatch) => ({
fetchDishes: () => dispatch(fetchDishes()),
fetchComments: () => dispatch(fetchComments()),
fetchPromos: () => dispatch(fetchPromos()),
fetchLeaders: () => dispatch(fetchLeaders()),
logoutUser: () => dispatch(logoutUser()),
});
const handleSignOut = () => {
//Here I have to dispatch logoutUser() but props.logoutUser() says undefined.
};
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView
style={styles.container}
forceInset={{ top: "always", horizontal: "never" }}
>
<View style={styles.drawerHeader}>
<View style={{ flex: 1 }}>
<Image
source={require("./images/newlogo.png")}
style={styles.drawerImage}
/>
</View>
<View style={{ flex: 2 }}>
<Text style={styles.drawerHeaderText}>Ristorante Con Fusion</Text>
</View>
</View>
<View style={styles.displayName}>
<Avatar
title={props.screenProps.name.match(/\b(\w)/g).join("")}
rounded
>
{" "}
</Avatar>
<Text style={{ fontSize: 22, marginLeft: 5, color: "#fff" }}>
Hello, {props.screenProps.name}
</Text>
</View>
<DrawerItems {...props} />
<TouchableOpacity onPress={() => handleSignOut()}> //Here I am calling the function
<View style={{ flexDirection: "row", justifyContent: "center" }}>
<Icon name="sign-out" type="font-awesome" size={24} color="blue" />
<Text>Sign Out</Text>
</View>
</TouchableOpacity>
</SafeAreaView>
</ScrollView>
);
const MainNavigator = createDrawerNavigator(
{
Home: {
screen: HomeNavigator,
navigationOptions: {
title: "Home",
drawerLabel: "Home",
drawerIcon: ({ tintColor, focused }) => (
<Icon name="home" type="font-awesome" size={24} color={tintColor} />
),
},
},
...
...
...
{
initialRouteName: "Home",
drawerBackgroundColor: "#D1C4E9",
contentComponent: CustomDrawerContentComponent,
}
);
class Main extends Component {
componentDidMount() {
this.props.fetchDishes();
this.props.fetchComments();
this.props.fetchPromos();
this.props.fetchLeaders();
};
render() {
var displayName = this.props.user.user.displayName;
if (displayName == undefined) displayName = this.props.user.name;
return (
<Fragment>
<View
style={{
flex: 1,
paddingTop:
Platform.OS === "ios" ? 0 : Expo.Constants.statusBarHeight,
}}
>
<MainNavigator screenProps={{ name: displayName }} />
</View>
</Fragment>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use the following to import useDispatch
import { useDispatch } from 'react-redux'
and then call it in your handleSignOut like so:
const handleSignOut = () => {
const dispatch = useDispatch()
dispatch(logoutUser())
//Continue with normal logout and maybe other dispatches...
};
Your component is not connected to redux. You are not using mapDispatchToProps anywhere else besides declaring it. Please use connect() method https://react-redux.js.org/api/connect

how to change header title in react native functional component?

i am using react-navigation v4 and i want to change the title and the approach i am using is slow while rendering(title that is set in the stack navigator is rendered first and then new one is rendered),is there better way i can render only the new one
export default NewsList = ({ results, navigation}) => {
return <View >
<FlatList
data={results}
keyExtractor={result => result.id}
renderItem={({ item }) => {
return (
<TouchableOpacity
onPress={() => navigation.navigate( 'news',title: item.title)}>
<NewsCard result={item} />
</TouchableOpacity>)
}}
/>
</View>
};
////////////////////////////////////////////////////////////////////
export default NewsScreen = ({ navigation}) => {
NewsScreen.navigationOptions = {
title: navigation.getParam("title");,
};
}
////////////////////////////////////////////////////////////////////
const NewsStack = createStackNavigator({
NewsList :NewsList,
News :NewsScreen
},{
initialRouteName:'NewsList',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#4BB5C3',
},
},
navigationOptions: {
tabBarLabel: 'NewsList',
},
});
export default createAppContainer(NewsStack);
Ciao, try to set title before navigate into NewsList like this:
export default NewsList = ({ results, navigation}) => {
return <View >
<FlatList
data={results}
keyExtractor={result => result.id}
renderItem={({ item }) => {
return (
<TouchableOpacity
onPress={() => {
navigation.setParams({ otherParam: item.title });
navigation.navigate('news');
}
}>
<NewsCard result={item} />
</TouchableOpacity>)
}}
/>
</View>
};
And I think you could remove navigationOptions in NewsScreen.

Navigating by Pressing Images

I am trying to navigate screens by pressing on specific images on SearchScreen.js. Each image leads to a different screen. I am currently trying to navigate from the first image to the screen meo_sw.js. However, I am not being able to do so and I don't undersand why. Here is the code of SearchScreen.js:
import React from 'react';
import { ScrollView, StyleSheet, TextInput, Text, View, Image, TouchableOpacity, TouchableWithoutFeedback} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
function SearchScreen() {
return (
<View style={styles.screen}>
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
<TouchableOpacity onPress={() => navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('vodaf_coura')}>
<Image source={require('../assets/images/vodafone_coura.png')} style={styles.image} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('superR_superB')}>
<Image source={require('../assets/images/superbock_superrock.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('nos_primavera')}>
<Image source={require('../assets/images/nos_primavera.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('rock_in_rio')}>
<Image source={require('../assets/images/rock_in_rio.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('edp_cool_jazz')}>
<Image source={require('../assets/images/edp_cooljazz.png')} style={styles.image}/>
</TouchableOpacity>
</ScrollView>
</View>
</View>
);
}
SearchScreen.navigationOptions = {
title: 'Procurar',
};
const styles = StyleSheet.create({
//I took this off because it's irrelevant for the question itself
});
export default SearchScreen;
And here is the screen 'meo_sw.js':
import React from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
const meo_sw = props => {
return(
<View style={styles.header}>
<Text style={styles.texto}>Meo Sudoeste</Text>
</View>
)
};
const styles=StyleSheet.create({
//Irrelevant
})
export default meo_sw;
The error says simply:
ReferenceError: Can't find variable: navigate
Please help me
UPDATED
This is the MainTabNavigator.js:
import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import SearchScreen from '../screens/SearchScreen';
import SettingsScreen from '../screens/SettingsScreen';
import ChatScreen from '../screens/ChatScreen';
import CalendarScreen from '../screens/CalendarScreen';
import meo_sw from '../Eventos/Festivais/meo_sw';
const config = Platform.select({
web: { headerMode: 'screen' },
default: {},
});
//Home
const HomeStack = createStackNavigator(
{
HomeScreen: {screen: HomeScreen},
SearchScreen: {screen: SearchScreen},
ChatScreen: {screen: ChatScreen},
SettingsScreen: {screen: SettingsScreen},
CalendarScreen: {screen: CalendarScreen},
},
config
);
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-home${focused ? '' : '-outline'}`
: 'md-home'
}
/>
),
};
HomeStack.path = '';
//Search
const SearchStack = createStackNavigator(
{
Search: SearchScreen,
},
config
);
SearchStack.navigationOptions = {
tabBarLabel: 'Procurar',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-search' : 'md-search'} />
),
};
SearchStack.path = '';
//Chat
const ChatStack = createStackNavigator(
{
Chat: ChatScreen,
},
config
);
ChatStack.navigationOptions = {
tabBarLabel: 'Chat',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-chatboxes${focused ? '' : '-outline'}`
: 'md-chatboxes'
}
/>
),
};
ChatStack.path = '';
//Settings
const SettingsStack = createStackNavigator(
{
Settings: SettingsScreen,
},
config
);
SettingsStack.navigationOptions = {
tabBarLabel: 'Perfil',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-person' : 'md-person'} />
),
};
SettingsStack.path = '';
//Calendar
const CalendarStack = createStackNavigator(
{
Calendar: CalendarScreen,
},
config
);
CalendarStack.navigationOptions = {
tabBarLabel: 'Calendário',
tabBarIcon: ({ focused }) => (
<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-calendar' : 'md-calendar'} />
),
};
CalendarStack.path = '';
//Bottom tab navigator
const tabNavigator = createBottomTabNavigator({
SearchStack,
CalendarStack,
HomeStack,
ChatStack,
SettingsStack
});
tabNavigator.path = '';
export default tabNavigator;
And this is the AppNavigator.js:
import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import MainTabNavigator from './MainTabNavigator';
export default createAppContainer(
createSwitchNavigator({
Main: MainTabNavigator,
})
);
Pass navigation object as prop.
function SearchScreen({ navigation }) {
....
}
The use it like
<TouchableOpacity onPress={() => navigation.navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
Add the screen to one of your navigators, like the following.
const HomeStack = createStackNavigator(
{
HomeScreen: { screen: HomeScreen },
SearchScreen: { screen: SearchScreen },
ChatScreen: { screen: ChatScreen },
SettingsScreen: { screen: SettingsScreen },
CalendarScreen: { screen: CalendarScreen },
meo_sw: { screen: meo_sw}
},
config
);
HomeStack.navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-home${focused ? '' : '-outline'}`
: 'md-home'
}
/>
),
};
Expo example
your Function is unable to get the props so that its not importing navigation property !!
change the function into class and get the props in class and then try navigating.
try this code
export default class SearchScreen extends Component {
constructor(props) {
super(props);
this.state = { }
}
return (
<View style={styles.screen}>
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('meo_sw')}>
<Image source={require('../assets/images/meo_sudoeste.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('vodaf_coura')}>
<Image source={require('../assets/images/vodafone_coura.png')} style={styles.image} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('superR_superB')}>
<Image source={require('../assets/images/superbock_superrock.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('nos_primavera')}>
<Image source={require('../assets/images/nos_primavera.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('rock_in_rio')}>
<Image source={require('../assets/images/rock_in_rio.png')} style={styles.image}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('edp_cool_jazz')}>
<Image source={require('../assets/images/edp_cooljazz.png')} style={styles.image}/>
</TouchableOpacity>
</ScrollView>
</View>
</View>
);
}
Hope it helps , feel free for doubts.

React Native - React Navigation Tab Bar - Custom floating action button

I need some help to use React Native - react navigation library.
It is Tab bar, but the Upload button acted as floating action button.
I have try :
const click = () => {
console.log('click');
return (
<View>
<Text>a</Text>
</View>
);
};
tabBarOnPress: (tab) => {
click();
},
// Main Page Navigator
export const Main = TabNavigator({
Home: {
screen: HomeNavigator,
},
Explore: {
screen: ExploreNavigator,
},
Upload: {
screen: UploadMain,
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'Upload',
tabBarIcon: ({ tintColor }) => (
<View>
<Icon name="camera" size={26} color={tintColor} />
</View>
),
tabBarOnPress: (tab) => {
click();
},
}),
},
}, {
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
backBehavior: 'none',
swipeEnabled: false,
lazy: true,
animationEnabled: false,
showIcon: true,
tabBarOptions: {
activeTintColor: 'black',
},
});
The Upload button is need to act as floating action button, when it clicked, it already logging, but not rendering the component.
Any workaround to create the floating action button?
I've some tricks like this https://github.com/react-navigation/react-navigation/pull/1335
But, it is only click and dispatch navigation, not doing floating action button
Regards,
Charlie
you should write this code to your component!
-- you can use ‘react-native-tab-navigator' --
import TabNavigator from 'react-native-tab-navigator';
...
render(){
// console.log('TabRouter this.state:',this.state);
let tabs = [<Home {...this.props}/>,<Chat {...this.props}/>,<Web {...this.props}/>,<User {...this.props}/>];
let a = this.state.loginData.tabList.map((item,key)=>{
// console.log('item:',item);
return(
<TabNavigator.Item
key={key}
selected={this.state.selectedTab === item.type}
title={item.name}
renderIcon={() => <Image source={{uri:item.iconUnselectedUrl}} style={{width:24,height:24,}}/>}
renderSelectedIcon={() => <Image source={{uri:item.iconSelectedUrl}} style={{width:24,height:24}} />}
badgeText={this.state.tabBadge}
onPress={() => this.setState({
selectedTab: item.type,
tabBadge:0,
})}
>
{tabs[key]}
</TabNavigator.Item>
)
});
// console.log('a:',a);
return(
<TabNavigator
hidesTabTouch={true}
sceneStyle={{backgroundColor:'#fff'}}>
{a[0]}
{a[1]}
<TouchableOpacity
key={'add'}
style={{}}
renderIcon={() => <View style={{borderRadius:5,backgroundColor:'#46aee3',
width:width/5,height:49,justifyContent:'center',alignItems:'center'}}>
<Text style={{fontSize:49,padding:0,color:'#ffffff',backgroundColor:'rgba(0,0,0,0)'}}>+</Text></View>}
onPress={()=>this.props.navigation.navigate('SendBlog')}
/>
{a[2]}
{a[3]}
</TabNavigator>
)
}
...
-- update 2018/01/22 --
I think you should
let that;
class UploadMain extends Component {
constructor(props){
super(props);
that = this;
this.state = {
change:false,
};
}
changeState = () => {
this.setState({change:!change});
};
navigationOptions: ({ navigation }) => ({
tabBarLabel: 'Upload',
tabBarIcon: ({ tintColor }) => (
<View>
{that.state.change ? <Text>loading...</Text>:<Icon name="camera" size={26} color={tintColor} />}
</View>
),
tabBarOnPress: () => {
that.changeState;
},
}),
render(){
return (
<View>
....
</View>
)
}
}
If you are using react-navigation version 5.x, you should use tabBarButton to modify.
the code detail you can read
https://medium.com/#my.maithi/react-native-navigation-add-custom-button-in-the-middle-of-tabbar-6c390201a2bb
Hope can help you.

Categories

Resources