import React, { Component } from 'react';
import { Alert, Button, TextInput, View, StyleSheet, Text, AsyncStorage } from 'react-native';
import { DrawerItems, DrawerNavigation } from 'react-navigation';
export default class Home extends Component {
const DrawerContent = (props) => (
<View>
<View
style={{
backgroundColor: '#f50057',
height: 140,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: 'white', fontSize: 30 }}>
Header
</Text>
</View>
<DrawerItems {...props} />
</View>
)
const Navigation = DrawerNavigator({
// ... your screens
Home:{
screen: HomeScreen,
},
Settings: {
screen: SettingsScreen,
},
}, {
// define customComponent here
contentComponent: DrawerContent,
})
render() {
return (
<View>
<Text>Welcome To Home</Text>
</View>
);
}
}
I am designing a screen which will be a home screen for my app. This screen will have navigation drawer like in Android and the drawer header will contain an image and a text label inside it and below that there will be drawer items from which i will navigate to a different screen. I have tried to achieve this using the above code but it doesn't work. Can you tell me where i am wrong? How can i achieve my target? I am a newbie to react native so i please make my concepts clear
Please replace your DrawerContent with the following code and check if it works.
const DrawerContent = (props) => {
return (
<SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
<View style={{ flexDirection: 'row', paddingBottom: 20 }}>
<View style={{ flex: 80, backgroundColor: '#f50057'}}>
<Image style={{ width: 181, height: 132}} source={images.logo} />
</View>
<Text style={{ color: '#000', fontSize: 30 }}>Header</Text>
</View>
<DrawerItems {...props}/>
</SafeAreaView>
)};
First create Drawer Component
export default class DrawerComponent extends React.Component {
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView>
<View style={{ backgroundColor: "white" }}>
<Image
style={{ margin: 15 }}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
</View>
<DrawerItems {...this.props} />
</ScrollView>
</SafeAreaView>
);
}
}
and import the component in your Home.js
import DrawerComponent from "./path/to/drawerComponent";
Please note : ScrollView is necessary for the case when you have more items to show ex: 7+ items (with margins in style prop) and also when screen height is small
Related
Currently, I'm getting the page this way after pressing on text input (notice there's no header, since it's popped out of the screen):
I want it to be like this (even if I press on text input, HEADER should remain in the same position):
I'm using this in the android manifest:
android:windowSoftInputMode="adjustPan"
Here's my code:
import React from 'react';
import {
View,
Dimensions,
TextInput,
ScrollView,
StatusBar,
Text,
KeyboardAvoidingView,
} from 'react-native';
const {width, height} = Dimensions.get('window');
const Conversation = ({}) => {
return (
<>
<StatusBar hidden />
<View
style={{
backgroundColor: 'gray',
height: 50,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text center style={{color: 'white'}}>
Header
</Text>
</View>
<KeyboardAvoidingView behavior="padding" style={{flex:1}}>
<TextInput
style={{
backgroundColor: 'white',
borderWidth: 1,
height: 50,
marginHorizontal: width * 0.1,
top: height * 0.9,
}}
/>
</KeyboardAvoidingView>
</>
);
};
export default Conversation;
You just need to remove top: height * 0.9 and place your content inside ScrollView.
import React from 'react';
import {
View,
Dimensions,
TextInput,
ScrollView,
StatusBar,
Text,
FlatList,
KeyboardAvoidingView,
} from 'react-native';
const { width, height } = Dimensions.get('window');
const Conversation = ({ }) => {
return (
<>
<StatusBar hidden />
<View
style={{
backgroundColor: 'gray',
height: 50,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text center style={{ color: 'white' }}>
Header
</Text>
</View>
<KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}>
<ScrollView>
</ScrollView>
<TextInput
style={{
backgroundColor: 'white',
borderWidth: 1,
height: 50,
marginHorizontal: width * 0.1
}}
/>
</KeyboardAvoidingView>
</>
);
};
export default Conversation
I saw that React Native offers nested vertical scroll-views from React Native Nested ScrollView Can`t Scroll on Android Device
The problem is that it doesn't seem to work on nested Horizontal ScrollViews on Android. See this code for an example:
https://snack.expo.io/#harrytravelchime/broken-horizontal-scroll
import React from 'react';
import _ from 'lodash';
import { View, ScrollView, StyleSheet, Text, SafeAreaView } from 'react-native';
export default class App extends React.PureComponent {
render() {
return (
<SafeAreaView style={styles.container}>
<ScrollView
style={{ height: '100%', width: '100%' }}
horizontal
nestedScrollEnabled
>
<View style={{ flexDirection: 'row' }}>
<ScrollView
style={{ width: 200, height: '100%' }}
horizontal
nestedScrollEnabled
>
<View style={{ flexDirection: 'row' }}>
{_.times(200, n => (
<View key={1000 + n} style={{ marginRight: 10 }}>
<Text>{1000 + n}</Text>
</View>
))}
</View>
</ScrollView>
{_.times(200, n => (
<View key={n} style={{ marginRight: 10 }}>
<Text>{n}</Text>
</View>
))}
</View>
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'stretch',
paddingVertical: 50,
},
});
On the other hand, the same code except with vertical scrolling totally works:
https://snack.expo.io/#harrytravelchime/working-vertical-scroll
Is there a way to make nested horizontal scrolling work?
One solution that I've come up with is to have a TouchableWithoutFeedback that tracks any touch by the user within the inner ScrollView. As soon as it detects a touch, it disables scrolling on the outer ScrollView, which would cause the inner ScrollView to receive events.
The main changes from the above code are:
Added state with outerScrollViewScrollEnabled
When the inner ScrollView is touched via the TouchableWithoutFeedback, change that state
Make the outer ScrollView's scrollEnabled depend on that
import React from "react";
import _ from "lodash";
import {
View,
ScrollView,
StyleSheet,
Text,
SafeAreaView,
TouchableWithoutFeedback
} from "react-native";
interface State {
outerScrollViewScrollEnabled: boolean;
}
export default class App extends React.PureComponent {
state = { outerScrollViewScrollEnabled: true };
handleInnerPressIn = () => this.setState({ outerScrollViewScrollEnabled: false });
handleInnerPressOut = () => this.setState({ outerScrollViewScrollEnabled: true });
render() {
const { outerScrollViewScrollEnabled } = this.state;
return (
<SafeAreaView style={styles.container}>
<ScrollView
style={{ height: "100%", width: "100%" }}
horizontal
scrollEnabled={outerScrollViewScrollEnabled}
>
<View style={{ flexDirection: "row" }}>
<ScrollView style={{ width: 200, height: "100%" }} horizontal>
<TouchableWithoutFeedback
onPressIn={this.handleInnerPressIn}
onPressOut={this.handleInnerPressOut}
>
<View style={{ flexDirection: "row" }}>
{_.times(200, n => (
<View key={1000 + n} style={{ marginRight: 10 }}>
<Text>{1000 + n}</Text>
</View>
))}
</View>
</TouchableWithoutFeedback>
</ScrollView>
{_.times(200, n => (
<View key={n} style={{ marginRight: 10 }}>
<Text>{n}</Text>
</View>
))}
</View>
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
alignItems: "stretch",
paddingVertical: 50
}
});
There is one more easier solution if you are using react-native-gesture-handler
import { ScrollView } from 'react-native'
import { ScrollView as GestureHandlerScrollView } from 'react-native-gesture-handler'
<ScrollView horizontal>
<GestureHandlerScrollView horizontal />
</ScrollVIew>
I got this answer from react-native github issue
import React from 'react';
import { Text, View } from 'react-native';
import { createDrawerNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'red', fontSize: 30 ,fontWeight: 'bold'}}>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'green' , fontSize: 20 ,fontWeight: 'bold'}}>Settings!</Text>
</View>
);
}
}
const MyDrawerNavigator = createDrawerNavigator({
Home:{
screen: HomeScreen,
},
Settings: {
screen: SettingsScreen,
},
});
export default createAppContainer(MyDrawerNavigator);
I was making navigation drawer with react native with above code.The problem which i faced is that drawer is not visible to me.I tried my best to solve this problem but i couldn't.Whats wrong with my code ?
you're missing the DrawerNavigatorConfig as a second parameter. There you config how the drawer displays and you set the content component to display within the drawer. Check the docs here: https://reactnavigation.org/docs/en/drawer-navigator.html
I tried react-native on Button which is working fine. I want to customize Button so this made me to go for TouchableOpacity. I am trying to setup react native navigation like below which is not working now.
I am using this for navigation https://reactnavigation.org/
index.android.js
/**
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from "react";
import {
AppRegistry,
Image,
View,
Text,
Button,
StyleSheet,
TouchableOpacity
} from "react-native";
import { StackNavigator } from "react-navigation";
import EnableNotificationScreen from "./EnableNotificationScreen";
import styles from "./Styles";
import * as strings from "./Strings";
class SplashScreen extends Component {
render() {
console.disableYellowBox = true;
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Image source={require("./img/talk_people.png")} />
<Text style={styles.textStyle}> {strings.talk_people} </Text>
<TouchableOpacity>
<View
style={{
backgroundColor: "#FE434C",
alignItems: "center",
justifyContent: "center",
borderRadius: 10,
width: 240,
marginTop: 30,
height: 40
}}
onPress={() => {
this.navigate("EnableNotifcation");
}}
>
<Text style={{ color: "white" }}>CONTINUE</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const ScheduledApp = StackNavigator(
{
Splash: {
screen: SplashScreen,
navigationOptions: {
header: {
visible: false
}
}
},
EnableNotification: {
screen: EnableNotificationScreen,
navigationOptions: {
header: {
visible: false
}
}
}
},
{
initialRouteName: "Splash"
}
);
AppRegistry.registerComponent("Scheduled", () => ScheduledApp);
It was a tpyo error at this line this.navigate("EnableNotifcation");
I corrected it and it is working now. this.navigate("EnableNotification");
The onPress prop should be inside TouchableOpacity, not inside of the View props like you have it. See the pseudo code below
<TouchableOpacity onPress = {...}>
<View style = {{}}>
//Rest of the code
This should fix it. On a sidenote, i would recommend adding a new style for your view component, theres a lot of elements in there :P
Edit:
<TouchableOpacity onPress = {/*do this*/}>
<View style={{ backgroundColor: "#FE434C",
alignItems: "center",
justifyContent: "center",
borderRadius: 10,
width: 240, marginTop: 30,
height: 40 }}>
<Text style={{ color: "white" }}>
{"CONTINUE"}
</Text>
</View>
</TouchableOpacity>
Using following worked for me. using react native 0.62.2. See TouchableOpacity is inside KeyboardAvoidingView and ScrollView keyboardShouldPersistTaps.
<ScrollView keyboardShouldPersistTaps="handled">
<KeyboardAvoidingView enabled>
<View>
<TouchableOpacity
onPress={() => functionNameToNavigate('ScreenToMoveOn')}> <Text>Click me</text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ScrollView>
I am learning React Native programming for Android mobile apps. I am making a screen where I need to set height of button. I have added button in view and set the height of using style however there is no change on button height.
/**
* LoginComponent of Myntra
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from "react";
import { AppRegistry, Text, View, Button, TextInput } from "react-native";
class LoginComponent extends Component {
render() {
return (
<View style={{ flex: 1, flexDirection: "column", margin: 10 }}>
<TextInput
style={{
height: 40,
borderColor: "gray",
borderWidth: 0.5
}}
placeholder="Email address"
underlineColorAndroid="transparent"
/>
<TextInput
style={{
height: 40,
borderColor: "gray",
borderWidth: 0.5
}}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid="transparent"
/>
<View style={{ height: 100, marginTop: 10 }}>
<Button title="LOG IN" color="#2E8B57" />
</View>
</View>
);
}
}
AppRegistry.registerComponent("Myntra", () => LoginComponent);
Can anyone help me to set the height of button according to my requirement?
This component has limited options, so you can't resize it to a fixed height.
I recommend you to use the TouchableOpacity component to build your own button, with own properties and styles.
You can easily style it like this:
<TouchableOpacity style={{ height: 100, marginTop: 10 }}>
<Text>My button</Text>
</TouchableOpacity>
You can set the button width as per the mentioned width easily by using following method :
<View style={[{ width: "90%", margin: 10, backgroundColor: "red" }]}>
<Button
onPress={this.buttonClickListener}
title="Button Three"
color="#FF3D00"
/>
</View>
Best solution is to use minHeight or maxHeight instead of using Height const.
It often happens that we want to change the dimensions of the button, which by default is extended to the entire width of the parent element. While reducing its width is not a problem – it is enough to reduce the width of the parent, but changing the height is already problematic. The Button element has no style property, so apart from changing the text color on iOS and the background color on Android, we can not set much in it.
To have more control over the button, it is better to use TouchableOpacity or TouchableNativeFeedback instead.
TouchableOpacity Function Component Example -
import React, { useState } from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
const App = () => {
const [count, setCount] = useState(0);
const onPress = () => setCount(prevCount => prevCount + 1);
return (
<View style={styles.container}>
<View style={styles.countContainer}>
<Text>Count: {count}</Text>
</View>
<TouchableOpacity
style={styles.button}
onPress={onPress}
>
<Text>Press Here</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingHorizontal: 10
},
button: {
alignItems: "center",
backgroundColor: "#DDDDDD",
padding: 10
},
countContainer: {
alignItems: "center",
padding: 10
}
});
export default App;
<View style={styles.btnContainer}>
<TouchableOpacity>
<Button style={styles.btnSize}>
<Text>Change Address</Text>
</Button>
</TouchableOpacity>
<TouchableOpacity>
<Button style={styles.btnSize}>
<Text>Change Address</Text>
</Button>
</TouchableOpacity>
</View>
Style sheet code snippet
const styles = StyleSheet.create({
btnContainer:{
flexDirection:"row",
justifyContent:"space-between"
},
btnSize:{
width:"100%"
}
})
The component Button supports a minimal level of customization, so you have to use an other component.
You can use : Pressable or TouchableOpacity ,
<Pressable onPress={onPressFunction} style={styles.yourButtonStyle}>
<Text>I'm pressable!</Text>
</Pressable
const styles = StyleSheet.create({
yourButtonStyle: {
...
}
});
Doc Button