I want to show a hamburger icon on the left side(it should be shown on all the header who uses drawer navigation) and post property button on the right side. I tried using headerRight and headerLeft but it is not showing any icons or buttons or whatever.
Here is what i have done
const SimpleStack = StackNavigator({
Home: {
screen: MyHomeScreen
},
PostProperty: {
screen: PostProperty
}
});
class DrawerView extends React.Component {
render() {
const { navigation } = this.props;
return (
<View>
<View style={{ backgroundColor: "red", padding: 100 }} />
<View style={{ padding: 20 }}>
<TouchableOpacity onPress={() => navigation.navigate("Rent")}>
<Text>Rent</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate("Buy")}>
<Text>Buy</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate("PostProperty")}>
<Text>Post Property</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const DrawerStack = DrawerNavigator(
{
Main: {
screen: SimpleStack
},
Rent: {
screen: Rent
},
Buy: {
screen: Buy
}
},
{
contentComponent: DrawerView,
drawerWidth: 280
}
);
export default DrawerStack;
const MyHomeScreen = ({ navigation }) => (
<View style={styles.container}>
<Text>Home</Text>
</View>
);
MyHomeScreen.navigationOptions = {
title: "RoomFinder",
drawer: {
icon: () => {
<Image source={require("../../assets/menu#2x.png")} />;
},
headerRight: <Button title="Post Property" />
}
};
const Rent = ({ navigation }) => (
<View>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={true}>
<View>
<Text>
Rent Screen
</Text>
</View>
</ScrollView>
</View>
);
Rent.navigationOptions = {
title: "Rent"
};
Related
I have a modal component that I want to reuse in future component.
For this reason I want to have it in its own file.
I don't manage to call the component inside the other properly though.
Here is my last attempt of it.
The Modal component code:
export const FlyingDescription = (cityDescription) => {
const [modalVisible, setModalVisible] = useState(false);
return (
<View>
<Modal
animation="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => setModalVisible(!modalVisible)}
>
<View style={styleBoxParent}>
<View style={styleBoxChildren}>
<LinearGradient
style={styleLinearGradient}
colors={['#136a8a', '#267871']}
start={[0, 0.65]}
>
<Text style={styleText}>{cityDescription}</Text>
<Pressable
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styleText}>Close</Text>
</Pressable>
</LinearGradient>
</View>
</View>
</Modal>
</View>
);
};
The component where I want to call the Modal component:
import FlyingDescription from './FlyingDescription.js';
var utils = require('./utils');
export default class SearchScreen extends React.Component {
constructor(props) {
super(props);
this.navigation = props.navigation;
this.state = {
searchInput: '',
item : {},
renderSearch: false,
renderFlyingDescription: false,
};
this.errorMessage = 'Search for cities...';
}
resetState = () => {
this.setState({
item: {},
renderable: false,
}); }
setSearchInput = (value) => {
this.setState({
searchInput: value
});
}
searchCity = () => {
this.resetState();
utils.fetchWeather(this.state.searchInput).then(response => {
if (response.cod == 200) {
console.log(response);
this.setItemState(
{
name: response.name,
temp: Math.ceil(response.main.temp),
type: response.weather[0].main,
desc: 'Humidity: ' + response.main.humidity + '% - ' + response.weather[0].main
}
);
this.setRenderSearch();
}
});
}
setItemState = (newItem) => {
this.setState(
{
item: newItem,
}
);
}
setRenderSearch = () => {
this.setState(
{
renderSearch: true,
}
);
}
render = () => {
return(
<View style={utils.style.container}>
<StatusBar barStyle="light-content" />
<Text style={utils.style.titleContainer}>☀️ CityWeather</Text>
<View style={{alignItems: 'center', width:'90%'}}>
<Text>Search for a city</Text>
<TextInput
onChangeText={(value) => this.setSearchInput(value)}
value={this.searchInput}
style={{ width: '80%', padding: 15, margin: 5, backgroundColor: 'black', color: 'white' }}
/>
<TouchableHighlight
style={{backgroundColor: 'grey', padding: 20, borderRadius: 8}}
onPress={this.searchCity}
>
<Text style={{fontSize: 14, color:'white'}}>Search</Text>
</TouchableHighlight>
</View>
{ this.state.renderSearch ? (
<TouchableHighlight
underlayColor="white"
onPress={ () => this.setState({renderFlyingDescription: true})}
>
<LinearGradient
colors={['rgba(0,0,0,0.05)', 'rgba(0,0,0,0)']}
start={[0, 0.5]}
>
<View style={utils.style.row}>
<Text style={[utils.getTempRange(this.state.item.temp), utils.style.temp]}>
{utils.getEmoji(this.state.item.type)} {this.state.item.temp} °C
</Text>
<Text style={utils.style.cityName}>{this.state.item.name}</Text>
</View>
</LinearGradient>
</TouchableHighlight>
) : (
// WHERE I WANT TO RENDER MY MODAL COMPONENT
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center', fontSize: 32}}>
<Text>{this.errorMessage}</Text>
</View>
)
}
{
renderFlyingDescription(this.state.renderFlyingDescription, this.state.item.desc)
}
</View>
);
}
}
export function renderFlyingDescription(isInterpretable, cityDescription) {
if(isInterpretable) {
return <FlyingDescription cityDescription={cityDescription} />
}
}
I have a button inside a custom drawer, however when trying to use a cross-screen navigation method on this button I get the following error: Error
I am using: "react-navigation": "^3.11.1", "react-native": "^0.60.4", "react": "16.8.6".
I am debugging the application on an S8 + with Android 8.0
const DEVICE_WIDTH = Dimensions.get('window').width;
const CustomDrawerComponent = props => (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<View style={{flexDirection:'row', backgroundColor:'#006bb3', height:100, flex:1, justifyContent:'center'}}>
<View style={{height:100,width:60, borderRadius:30,justifyContent:'center'}}>
<Image source={require('../../assets/no-login.png')} style={{height:40,width:40, borderRadius:20}}></Image>
</View>
<View style={{justifyContent:'center', height:100}}>
<Text style={{color:'white', fontSize:15, fontWeight:'700'}}>Acesse sua conta agora!</Text>
<Text style={{color:'white', fontSize:14, fontWeight:'600', textDecorationLine:'underline'}}>Clique aqui!</Text>
</View>
</View>
<DrawerItems {...props} />
<TouchableOpacity
style={{height:50, justifyContent:'center'}}
onPress={this.logout}
>
<View style={{marginBottom:0, flexDirection:'row'}}>
<View style={{marginLeft:14}}>
<Icon name='login-variant'type='MaterialCommunityIcons' style={{color:'grey' ,fontSize:25}}/>
</View>
<View style={{marginLeft:27}}>
<Text style={{fontSize:15, fontWeight:'700', color:'grey'}}> Sair da Conta</Text>
</View>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
const AppDrawerNavigator = createDrawerNavigator(
{
Home:{
screen:HomeScreen,
navigationOptions:{
drawerLabel:'Home',
drawerIcon: ({tintColor}) =>
(<Icon name='home'type='FontAwesome' style={{color:tintColor, fontSize:25}}/>)
},
},
HomeLogin:{
screen:HomeLogin,
navigationOptions:{
drawerLabel: () => null,
},
},
Login:{
screen:LoginScreen,
navigationOptions:{
drawerLabel: () => null
}
},
Register:{
screen:RegisterScreen,
navigationOptions:{
drawerLabel: () => null
},
headerStyle:{
backgroundColor:'#006bb3',
},
headerTitleStyle:{
fontWeight:'bold',
},
title:'Cadastre-se!'
},
},
{
drawerWidth: DEVICE_WIDTH*0.7,
initialRouteName:'Home',
contentComponent: CustomDrawerComponent,
contentOptions:{
activeTintColor:'#006bb3',
labelStyle:{
fontSize:14,
},
}
}
);
logout = () =>{
this.props.navigation.navigate('Login')
}
const Menu = createAppContainer(AppDrawerNavigator);
//export default connect(mapStateToProps, mapDispatchToProps) (Menu)
export default Menu
I was hoping that clicking on the "Sair da conta" button would navigate to the 'Login' screen.
You didn't deliver props to the object. And you don't have to make a function in a simple command syntax.
onPress={() => this.props.navigation.navigate('Login')}
...
contentComponent: props => < CustomDrawerComponent {...props} />,
how is it possible to position the menu point at the lower edge of the screen?
The best solution would be if you could simply change the style of the navigation options for each element.
Here is my App Navigator:
const AppNavigator = createDrawerNavigator(
{
Einkaufsliste: {
screen: MainScreen,
navigationOptions: {
drawerIcon: <Icon name="shopping-cart" />
}
},
Bearbeiten: {
screen: BasketEditScreen,
navigationOptions: {
drawerIcon: <Icon name="edit" />
}
}
},
{
contentComponent: CustomDrawerComponent
}
);
Thanks!
According to react-navigation you can make a custom Drawer navigator, so what you need is to create a similar thing to their example:
import { DrawerItems, SafeAreaView } from 'react-navigation';
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
<DrawerItems {...props} />
</SafeAreaView>
</ScrollView>
);
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
So in your case what you want to do is:
import { DrawerItems, SafeAreaView } from 'react-navigation';
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
<View style={{flex: 1 }}>
<DrawerItems {...props} />
</View>
<TouchableOpacity style={{flexDirection: 'row', alignItems: 'center'}}>
//Your pencil icon here with correct margin to the right
<Text>Bearbeiten</Text>
</TouchableOpacity>
</SafeAreaView>
</ScrollView>
);
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
I am using createDrawerNavigator and inside this I made a custom profile view. When I press navigate I want to move to another screen.
But this give me an error undefined is not an object (evaluating"_this.props.navigation"). Other components one, two, three works fine.
This is my code:
export default class App extends Component {
render() {
return (
<View style={{flex:1, marginTop:30}}>
<AppContainer/>
</View>
);
}
}
const CustomDrawerContentComponent = (props)=> {
return(
<SafeAreaView style={{flex:1}}>
<View style={{ height:100, backgroundColor: '#9FA8DA' }}>
<Image
style={{marginLeft:20,height:100,width:100,borderRadius:50}}
source={require('./assets/puppy.jpg')}/>
</View>
<View style={{flexDirection:'row', margin:20, alignItems:'center'}}>
//////here is where I get an error
<TouchableOpacity
style={{marginTop:0}}
onPress={()=> {this.props.navigation.navigate('profile')}}>
<Text style={{fontSize:18, fontWeight:'bold'}}>navigate</Text>
<Image
style={{height:12,width:12}}
source={require('./assets/drawable-hdpi/ic_arrow_depth.png')}/>
</TouchableOpacity>
</View>
<ScrollView>
<DrawerItems {...props}/>
</ScrollView>
</SafeAreaView>
)
}
const AppDrawerNavigator = createDrawerNavigator({
one: AppStackNavigator,
two: BoardScreen,
three: NotificationScreen,
},{
contentComponent:CustomDrawerContentComponent,
})
const AppStackNavigator = createStackNavigator({
profile: {
screen: profileScreen,
navigationOptions: {
header: null
},
},
})
const StartSwitchNavigator = createSwitchNavigator(
{
App: AppDrawerNavigator,
},
{
initialRouteName: 'App',
}
)
Your CustomDrawerContentComponent component is functional component. Use props.navigation directly instead of this.props
I'm using "react-navigation": "^2.11.2" and have a TabNavigator() with 3 tabs: A, B and C.
So I use:
...
_Profile: {
screen: TabNavigator(
{
First: A,
Second: B,
Third: C
},
{
tabBarPosition: "top",
swipeEnabled: true,
lazy: false
}
),
navigationOptions: ({ navigation }) => ({
header: <ProfileHeader navigation={navigation} />
})
},
...
I want to have a fixed footer in Pages A and B but NOT in C.
First I tried to create a footer in each A and B but the result is something different from what I want, See images below:
But when I try to swipe to tab B, You can see the footer is NOT FIXED:
Any idea about this?
Thanks in advance!
I asked the contributors and we have a full example from now on:
Custom Tabs with footer:
Github example
UPDATE
I guess the link is broken so I paste the code here:
import React from "react";
import {
LayoutAnimation,
View,
StyleSheet,
StatusBar,
Text
} from "react-native";
import { SafeAreaView, createMaterialTopTabNavigator } from "react-navigation";
import Ionicons from "react-native-vector-icons/Ionicons";
import { Button } from "./commonComponents/ButtonWithMargin";
class MyHomeScreen extends React.Component {
static navigationOptions = {
tabBarLabel: "Home",
tabBarIcon: ({ tintColor, focused, horizontal }) => (
<Ionicons
name={focused ? "ios-home" : "ios-home"}
size={horizontal ? 20 : 26}
style={{ color: tintColor }}
/>
)
};
render() {
const { navigation } = this.props;
return (
<SafeAreaView forceInset={{ horizontal: "always", top: "always" }}>
<Text>Home Screen</Text>
<Button
onPress={() => navigation.navigate("Home")}
title="Go to home tab"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
</SafeAreaView>
);
}
}
class RecommendedScreen extends React.Component {
static navigationOptions = {
tabBarLabel: "Recommended",
tabBarIcon: ({ tintColor, focused, horizontal }) => (
<Ionicons
name={focused ? "ios-people" : "ios-people"}
size={horizontal ? 20 : 26}
style={{ color: tintColor }}
/>
)
};
render() {
const { navigation } = this.props;
return (
<SafeAreaView forceInset={{ horizontal: "always", top: "always" }}>
<Text>Recommended Screen</Text>
<Button
onPress={() => navigation.navigate("Home")}
title="Go to home tab"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
</SafeAreaView>
);
}
}
class FeaturedScreen extends React.Component {
static navigationOptions = ({ navigation }) => ({
tabBarLabel: "Featured",
tabBarIcon: ({ tintColor, focused, horizontal }) => (
<Ionicons
name={focused ? "ios-star" : "ios-star"}
size={horizontal ? 20 : 26}
style={{ color: tintColor }}
/>
)
});
render() {
const { navigation } = this.props;
return (
<SafeAreaView forceInset={{ horizontal: "always", top: "always" }}>
<Text>Featured Screen</Text>
<Button
onPress={() => navigation.navigate("Home")}
title="Go to home tab"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
</SafeAreaView>
);
}
}
const SimpleTabs = createMaterialTopTabNavigator({
Home: MyHomeScreen,
Recommended: RecommendedScreen,
Featured: FeaturedScreen
});
class TabNavigator extends React.Component {
static router = SimpleTabs.router;
componentWillUpdate() {
LayoutAnimation.easeInEaseOut();
}
render() {
const { navigation } = this.props;
const { routes, index } = navigation.state;
const activeRoute = routes[index];
let bottom = null;
if (activeRoute.routeName !== "Home") {
bottom = (
<View style={{ height: 50, borderTopWidth: StyleSheet.hairlineWidth }}>
<Button title="Check out" onPress={() => {}} />
</View>
);
}
return (
<View style={{ flex: 1 }}>
<StatusBar barStyle="default" />
<SafeAreaView
style={{ flex: 1 }}
forceInset={{ horizontal: "always", top: "always" }}
>
<SimpleTabs navigation={navigation} />
</SafeAreaView>
{bottom}
</View>
);
}
}
export default TabNavigator;