I implemented Drawer code and installed Drawer from its original docs and added Drawer into my Project, but I can't see drawer, tried playing with flex but in vain
Here are my code, any and every help is highly appreciated
Thank you
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View >
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
const [selectedValue, setSelectedValue] = useState(' ');
const [text, setText] = useState('');
const [data, setData] = useState(['']);
const [totalAmount, setTotalAmount] = useState(0)
return (
<TouchableWithoutFeedback onPress={() => {
Keyboard.dismiss();
}}>
<View style={styles.container}>
<View >
<Header />
<View style={styles.row}>
<TextInput style={styles.input}
underlineColorAndroid="transparent"
placeholder=" Amount "
placeholderTextColor="#9a73ef"
autoCapitalize="none"
keyboardType='numeric'
onChangeText={text => setText(text)}
value={text}
/>
<Picker
selectedValue={selectedValue}
style={{ height: 50, width: 150 }}
onValueChange={(itemValue, itemIndex) => setSelectedValue(itemValue)}
>
<Picker.Item value= " " label='Select Option' />
<Picker.Item label="Food" value="Food" />
<Picker.Item label="Transport" value="Transport" />
<Picker.Item label="Rent" value="Rent" />
<Picker.Item label="Other" value="Other " />
</Picker>
</View>
And here i put my DRAWER
<Text>TOTAL : {totalAmount}</Text>
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
<Button
title="Save"
color="#841584"
accessibilityLabel="Learn more about this purple button"
onPress={() => {
if (text == 0 ) {
alert('Please enter the Amount ')
}
if (text && selectedValue != " "){
setData([...data, { name: text, selectedValue: selectedValue }
])
setTotalAmount(totalAmount + parseInt(text))
}}
}
/>
<View styles={styles.list}>
<FlatList
data={data}
renderItem={({ item }) => <React.Fragment>
<Text style={styles.item}> {item.name}$ Spend on "
{item.selectedValue}"</Text>
</React.Fragment>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
</View>
</TouchableWithoutFeedback>
)};
Here is the styles for my project
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
input: {
margin: 15,
height: 40,
borderColor: 'black',
borderWidth: 2,
width: 80,
flex: 1,
},
input2: {
margin: 15,
height: 40,
borderColor: 'black',
borderWidth: 2,
width: 80,
flex: 1,
},
row: {
flexDirection: 'row'
},
item: {
textAlign: 'center',
marginTop: 20,
padding: 20,
fontSize: 20,
backgroundColor: 'steelblue'
},
list: {
marginTop: 20,
flex: 1
},
button: {
}
});
also in , i have header file
export default function Header() {
return (
<View style={styles.header}>
<Text style={styles.title}>Мои расходы </Text>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
const styles = StyleSheet.create({
header: {
height: 80,
paddingTop: 38,
backgroundColor: 'red'
},
title: {
textAlign: 'center',
color: '#fff',
fontSize: 20,
fontWeight: 'bold'
}
})
Swipe Left to Right, Just check Your Drawer Came out or not. If Not then Your Drawer is not set up as mentioned in the document. Make a button on your header and onPress Method just call {() => this.props.navigation.openDrawer()}
Related
I have a react-native application drawer. In the navigation pane i want to apply background color of orange. Colors are being stored as a constant named as themed and the orange color is named as primary. The navigation is not applying the color to its background. Also i want to rescale the main application screen whenever the navigation panel is opened. That is not working too. I am using react-navigation v6.
This is my app.js file.
import React from 'react';
import {createStackNavigator} from '#react-navigation/stack';
import {NavigationContainer} from '#react-navigation/native';
import CustomDrawer from './navigation/CustomDrawer';
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
initialRouteName={'Home'}>
<Stack.Screen name="Home" component={CustomDrawer} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
This is my mainLayout.js file
import React from 'react';
import {View, Text} from 'react-native';
import Animated from 'react-native-reanimated';
const MainLayout = ({drawerAnimationStyle}) => {
return (
<Animated.View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
...drawerAnimationStyle,
}}>
<Text>MainLayout</Text>
</Animated.View>
);
};
export default MainLayout;
This is how my customNavigation.js file looks like
/* eslint-disable react/self-closing-comp */
/* eslint-disable react-native/no-inline-styles */
import React, {useState} from 'react';
import {View, Text, Image, TouchableOpacity} from 'react-native';
import {
createDrawerNavigator,
DrawerContentScrollView,
} from '#react-navigation/drawer';
import {MainLayout} from '../screens';
import {COLORS, FONTS, SIZES, icons, constants, dummyData} from '../constants';
import Animated from 'react-native-reanimated';
const Drawer = createDrawerNavigator();
const CustomDrawerItem = ({label, icon}) => {
return (
<TouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
marginBottom: SIZES.base,
height: 40,
paddingLeft: SIZES.base,
borderRadius: SIZES.base,
//borderColor
}}
// onPress
>
<Image
source={icon}
style={{
height: 20,
width: 20,
tintColor: COLORS.black,
}}
/>
<Text
style={{
marginLeft: 15,
color: COLORS.black,
...FONTS.h3,
}}>
{label}
</Text>
</TouchableOpacity>
);
};
const CustomDrawerContent = ({navigation}) => {
return (
<DrawerContentScrollView
scrollEnabled={true}
contentContainerStyle={{flex: 1}}>
<View
style={{
flex: 1,
paddingHorizontal: SIZES.radius,
}}>
{/* Close */}
<View
style={{
alignItems: 'flex-start',
justifyContent: 'center',
}}>
<TouchableOpacity
style={{
alignItems: 'center',
justifyContent: 'center',
}}
onPress={() => navigation.closeDrawer()}>
<Image
source={icons.cross}
style={{
height: 35,
width: 35,
tintColor: COLORS.black,
}}
/>
</TouchableOpacity>
</View>
{/* Profile */}
<TouchableOpacity
style={{
flexDirection: 'row',
marginTop: SIZES.radius,
alignItems: 'center',
}}
onPress={() => console.log('Profile Button Clicked')}>
<Image
source={dummyData.myProfile?.profile_image}
style={{
height: 50,
width: 50,
borderRadius: SIZES.radius,
}}
/>
<View
style={{
marginLeft: SIZES.radius,
}}>
<Text style={{color: COLORS.black, ...FONTS.h3}}>
{dummyData.myProfile?.name}
</Text>
<Text style={{color: COLORS.black, ...FONTS.body4}}>
View your profile
</Text>
</View>
</TouchableOpacity>
{/* Drawer Items */}
<View
style={{
flex: 1,
marginTop: SIZES.padding,
}}>
<CustomDrawerItem label={constants.screens.home} icon={icons.home} />
<CustomDrawerItem
label={constants.screens.my_wallet}
icon={icons.wallet}
/>
<CustomDrawerItem
label={constants.screens.notification}
icon={icons.notification}
/>
<CustomDrawerItem
label={constants.screens.favourite}
icon={icons.favourite}
/>
{/* Line Divider */}
<View
style={{
height: 1,
marginVertical: SIZES.radius,
marginLeft: SIZES.radius,
backgroundColor: COLORS.lightGray1,
}}></View>
{/* Drawer Items */}
<CustomDrawerItem label="Track Your Items" icon={icons.location} />
<CustomDrawerItem label="Coupons" icon={icons.coupon} />
<CustomDrawerItem label="Settings" icon={icons.setting} />
<CustomDrawerItem label="Invite a Friend" icon={icons.profile} />
<CustomDrawerItem label="Settings" icon={icons.setting} />
<CustomDrawerItem label="Help Center" icon={icons.help} />
</View>
{/* Logout */}
<View
style={{
marginBottom: SIZES.padding,
}}>
<CustomDrawerItem label="Logout" icon={icons.logout} />
</View>
</View>
</DrawerContentScrollView>
);
};
const CustomDrawer = () => {
const [progress, setProgress] = useState(new Animated.Value(0));
const scale = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [1, 0.8],
});
const borderRadius = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [0, 26],
});
const animatedStyle = {borderRadius, transform: [{scale}]};
return (
<View
style={{
flex: 1,
backgroundColor: COLORS.primary,
}}>
<Drawer.Navigator
overLayColor="transparent"
drawerStyle={{
flex: 1,
width: '65%',
paddingRight: 20,
backgroundColor: 'transparent',
}}
sceneContainerStyle={{
backgroundColor: 'transparent',
}}
screenOptions={{
headerShown: false,
drawerType: 'front',
}}
initialRouteName="MainLayout"
drawerContent={props => {
setTimeout(() => {
setProgress(props.progress);
}, 0);
return <CustomDrawerContent navigation={props.navigation} />;
}}>
<Drawer.Screen name="MainLayout">
{props => (
<MainLayout {...props} drawerAnimationStyle={animatedStyle} />
)}
</Drawer.Screen>
</Drawer.Navigator>
</View>
);
};
export default CustomDrawer;
I was watching a training video. In the video, he was doing the login process with firebase. At the same time, the application was redirecting the user to another page if logged in. I did what had to be done, but when I click the login button, a white screen greets me. Could you please tell me where I went wrong?
HomeStack.js
import { View, Text } from 'react-native'
import React from 'react'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
import LoginScreen from '../screens/Auth/LoginScreen'
import SignUpScreen from '../screens/Auth/SignUpScreen'
import ResetPasswordScreen from '../screens/Auth/ResetPasswordScreen'
import HomeScreen from '../screens/Home/HomeScreen'
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const BottomTab = () => {
return (
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen
name='HomeScreen'
component={HomeScreen}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
)
}
const HomeStack = () => {
return (
<Stack.Navigator initialRouteName="BottomTab">
<Stack.Screen
name="BottomTab"
component={BottomTab}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
)
}
export default HomeStack
AuthStack.js
import { View, Text } from 'react-native'
import React from 'react'
import { createNativeStackNavigator } from '#react-navigation/native-stack'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
import LoginScreen from '../screens/Auth/LoginScreen'
import SignUpScreen from '../screens/Auth/SignUpScreen'
import ResetPasswordScreen from '../screens/Auth/ResetPasswordScreen'
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const BottomTabStack = () => {
return (
<Stack.Navigator initialRouteName="LoginScreen">
<Stack.Screen
name='LoginScreen'
component={LoginScreen}
options={{
headerShown: false,
}}
/>
<Stack.Screen
name='SignUpScreen'
component={SignUpScreen}
options={{
headerShown: false,
}}
/>
<Stack.Screen
name='ResetPasswordScreen'
component={ResetPasswordScreen}
options={{
headerShown: false,
}}
/>
</Stack.Navigator>
)
}
const AuthStack = () => {
return (
<Stack.Navigator initialRouteName="BottomTabStack">
<Stack.Screen
name="BottomTabStack"
component={BottomTabStack}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
)
}
export default AuthStack
and LoginScreen.js
import { View, Text, SafeAreaView, TouchableOpacity, ScrollView, TextInput, Button } from 'react-native'
import React, { useContext } from 'react'
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
import { AuthContext } from '../../navigation/AuthProvider'
import { Formik, validateYupSchema } from 'formik'
import * as yup from 'yup'
const color = '#aaa';
const LoginScreen = ({ navigation }) => {
const { login } = useContext(AuthContext);
const loginValidationSchema = yup.object().shape({
email: yup
.string()
.required("Boş Geçilemez")
.email("Geçerli bir email giriniz!"),
password: yup
.string()
.required("Boş Geçilemez")
.min(6, ({ min }) => 'Şifre en az' + min + 'karakterden olmalıdır')
});
return (
<SafeAreaView style={{ width: '100%', height: '100%' }}>
<View style={{
width: '100%',
height: '90%',
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
width: '75%',
alignItems: 'center',
padding: 10,
backgroundColor: '#ddd',
borderRadius: 30
}}>
<Text style={{fontSize:24,color:'#000'}}>Üye Girişi</Text>
<Formik
validationSchema={loginValidationSchema}
initialValues={{ email: '', password: '' }}
onSubmit={values => login(values.email, values.password)}>
{({ handleChange, handleBlur, handleSubmit, values, errors, isValid,
}) => (
<>
<TextInput
name="email"
placeholder='Email Adresiniz'
style={{
height: 50,
width: '90%',
margin: 10,
borderColor: '#000',
borderWidth: 1,
borderRadius: 10,
padding: 10,
fontSize: 16
}}
onChangeText={handleChange('email')}
onBlur={handleBlur('email')}
value={values.email}
keyboardType="email-address"
/>
{errors.email && <Text style={{ color: '#f00', fontSize: 14 }}>{errors.email}</Text>}
<TextInput
name="password"
placeholder='Şifreniz'
style={{
height: 50,
width: '90%',
margin: 10,
borderColor: '#000',
borderWidth: 1,
borderRadius: 10,
padding: 10,
fontSize: 16
}}
onChangeText={handleChange('password')}
onBlur={handleBlur('password')}
value={values.password}
keyboardType="visible-password"
secureTextEntry
/>
{errors.password && (<Text style={{ color: '#f00', fontSize: 14 }}>{errors.password}</Text>)}
<View style={{ width: '60%' }}>
<Button style={{margin:10}}
color='#d55'
onPress={handleSubmit}
disabled={!isValid}
title="Giriş" />
</View>
</>
)}
</Formik>
</View>
</View>
<View style={{
backgroundColor: '#fff',
width: '100%',
height: 75,
bottom: 0,
position: 'absolute',
flexDirection: 'row'
}}>
<TouchableOpacity style={{
flex: 1,
}} onPress={() => {
navigation.navigate("LoginScreen")
}}>
<View style={{
backgroundColor: '#fff',
flex: 1,
height: 75,
bottom: 0,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
}}>
<IconFA5 name='user-shield' color={'#d55'} size={30} />
<Text style={{ fontSize: 20, color: '#d55' }}>Giriş Yap</Text>
</View></TouchableOpacity>
<TouchableOpacity style={{
flex: 1,
}} onPress={() => {
navigation.navigate("SignUpScreen")
}}>
<View style={{
backgroundColor: '#fff',
flex: 1,
height: 75,
bottom: 0,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
}}>
<IconFA5 name='user-plus' color={color} size={30} />
<Text style={{ fontSize: 20, color: color }}>Kayıt OL</Text>
</View></TouchableOpacity>
<TouchableOpacity style={{
flex: 1,
}} onPress={() => {
navigation.navigate("ResetPasswordScreen")
}}>
<View style={{
backgroundColor: '#fff',
flex: 1,
height: 75,
bottom: 0,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
}}>
<IconFA5 name='key' color={color} size={30} />
<Text style={{ fontSize: 20, color: color }}>Şifre Değiştir</Text>
</View></TouchableOpacity>
</View>
</SafeAreaView>
)
}
export default LoginScreen
You can check this article about the authentication flows. https://reactnavigation.org/docs/auth-flow/
Basically it's about the conditional rendering. You should store state about isLogin (async-storage etc.)
return (
<NavigationContainer>
<Stack.Navigator>
isLogin ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
);
</Stack.Navigator>
</NavigationContainer>
)
I'm using React Native for my app. Everything is going well except one thing.
I would like to implement a modal view that is displayed when the user clicks on the middle button (+) of the tabbar. It looks like the Youtube app.
After serveral days, I didn't find an effective solution.
Here is my code for the the tabbar and the navigator.
Tabbar :
export default function App() {
return (
<NavigationContainer >
<Tabs.Navigator tabBarOptions={{labelStyle: {fontSize:14}, activeTintColor: 'purple', showLabel: false} }
>
<Tabs.Screen name="Ventes" component={venteScreenNavigator}
options={{
headerShown: false,
tabBarIcon: ({ focused }) => (
<View style={{ alignItems: "center", justifyContent: "center" }}>
<Image
source={require("./assets/Buy.png")}
resizeMode="contain"
style={{
width: 25,
height: 25,
tintColor: focused ? "black" : "gray",
}}
/>
</View>
),
}}
/>
<Tabs.Screen name="Map" component={mapScreenNavigator}
options={{
headerShown: false,
tabBarIcon: ({ focused }) => (
<View style={{ alignItems: "center", justifyContent: "center" }}>
<Image
source={require("./assets/geolocalisationicone.png")}
resizeMode="contain"
style={{
width: 25,
height: 25,
tintColor: focused ? "black" : "gray",
}}
/>
</View>
)
}}
/>
<Tabs.Screen name="Liste" component={listeScreenNavigator}
options={{
headerShown: false,
tabBarIcon: ({ focused }) => (
<View style={{ alignItems: "center", justifyContent: "center" }}>
<Image
source={require("./assets/Document.png")}
resizeMode="contain"
style={{
width: 25,
height: 25,
tintColor: focused ? "black" : "gray",
}}
/>
</View>
),
}}
/>
<Tabs.Screen name="Espace" component={espaceScreenNavigator}
options={{
headerShown: false,
tabBarIcon: ({ focused }) => (
<View style={{ alignItems: "center", justifyContent: "center" }}>
<Image
source={require("./assets/monespaceicone.png")}
resizeMode="contain"
style={{
width: 25,
height: 25,
tintColor: focused ? "black" : "gray",
}}
/>
</View>
),
}}
/>
</Tabs.Navigator>
</NavigationContainer>
)
}
Nav :
const venteScreenNavigator = () => {
return (
<stack.Navigator>
<stack.Screen name="Ventes" component={Ventes}
options={{
headerRight: ()=> (
<View style={{flexDirection: 'row', marginRight: 10}}>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Plus.png')}>
</Image>
</TouchableOpacity>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Chat.png')}>
</Image>
</TouchableOpacity>
</View>
)
}}
/>
<stack.Screen name="Screens" component={Screens}
/>
</stack.Navigator>
)
}
export {venteScreenNavigator}
const mapScreenNavigator = () => {
return (
<stack.Navigator>
<stack.Screen name="Map" component={Map}
options={{
headerRight: ()=> (
<View style={{flexDirection: 'row', marginRight: 10}}>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Plus.png')}>
</Image>
</TouchableOpacity>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Chat.png')}>
</Image>
</TouchableOpacity>
</View>
)
}}
/>
<stack.Screen name="Screens" component={Screens}
/>
</stack.Navigator>
)
}
export {mapScreenNavigator}
const listeScreenNavigator = () => {
return (
<stack.Navigator>
<stack.Screen name="Liste" component={Liste}
options={{
headerRight: ()=> (
<View style={{flexDirection: 'row', marginRight: 10}}>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Plus.png')}>
</Image>
</TouchableOpacity>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Chat.png')}>
</Image>
</TouchableOpacity>
</View>
)
}}
/>
<stack.Screen name="Screens" component={Screens}
/>
</stack.Navigator>
)
}
export {listeScreenNavigator}
const espaceScreenNavigator = () => {
return (
<stack.Navigator>
<stack.Screen name="Espace" component={Espace}
options={{
headerRight: ()=> (
<View style={{flexDirection: 'row', marginRight: 10}}>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Plus.png')}>
</Image>
</TouchableOpacity>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Chat.png')}>
</Image>
</TouchableOpacity>
</View>
)
}}
/>
<stack.Screen name="Screens" component={Screens}
/>
<stack.Screen name="Profil" component={Profil}
options={{
headerRight: ()=> (
<View style={{flexDirection: 'row', marginRight: 10}}>
<TouchableOpacity>
<Image
style={styles.image}
source={require('../assets/Setting.png')}>
</Image>
</TouchableOpacity>
</View>
)
}}
/>
<stack.Screen name="ModifierProfil" component={ModifierProfil}
/>
</stack.Navigator>
)
}
export {espaceScreenNavigator}
Can you please tell me how to do displayed the modal when the user clicks on the tabbar button ?
Thanks guys !
**Try this code**
const PopUpTask = ({navigation}) => {
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', e => {
// Prevent default behavior
e.preventDefault();
// Here you create it
alert('Default behavior prevented');
// Do something manually
// ...
});
return unsubscribe;
}, [navigation]);
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Home!</Text>
</View>
);
};
I am using a FlatList in my code like this:
<View style={styles.listHolder}>
{data && (
<FlatList
data={data.me.friends.nodes}
horizontal={false}
scrollEnabled
renderItem={({ item }) => (
<FriendItem friend={item} originatorId={data.me.id}/>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={NoFriendsContainer}
/>
)}
{error && <ErrorContainer />}
</View>
listHolder: {
width: '100%',
alignItems: 'center',
},
Each of the FriendItem looks somewhat like this:
return (
<View style={styles.item}>
<TouchableOpacity
onPress={() =>
navigation.navigate('FriendDetails', {
firstName: friend.firstName,
rating: friend.rating,
numberOfFriends: friend.friendsOfFriends?.totalCount,
//onDeleteFriend: onDeleteFriend,
vehicles: friend.vehicles,
})
}>
<Thumbnail
style={styles.thumbnail}
source={{
uri:
'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png',
}} />
</TouchableOpacity>
<View style={styles.nameContainer}>
<Text style={styles.userName}>{userName}</Text>
</View>
<View style={styles.deleteButtonContainer}>
<Button
rounded
style={styles.deleteButton}
onPress={() => onDeleteFriend(originatorId, friend.id)}>
<Icon name="trash-o" size={moderateScale(20)} color="black" />
</Button>
</View>
</View>
);
};
export const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
borderRadius: moderateScale(20),
padding: moderateScale(20),
marginVertical: moderateScale(8),
marginHorizontal: 16,
height: moderateScale(110),
width: moderateScale(360),
justifyContent: 'space-between',
flexDirection: 'row',
},
userName: {
paddingRight: 55,
paddingLeft: 10,
paddingTop: 20,
},
deleteButton: {
backgroundColor: '#31C283',
width: moderateScale(45),
justifyContent: 'center',
},
deleteButtonContainer: {
paddingTop: 12,
marginRight: 2,
},
thumbnail: {
height: 85,
width: 85,
marginLeft: 2,
paddingRight: 0,
position: 'relative',
},
nameContainer: {
flexDirection: 'row',
},
});
Now the problem is that the FlatList is rendered vertically but its scroll bar is shown horizontally (which shouldn't happen). Additionally, I can move it in any direction right now. This should also not happen. I must fix it as it is. How can I do so? I am not sure if this is a styling issue or something in the FlatList component.
an you add the alwaysBounceVertical in the elow flatlist,
<FlatList
data={data.me.friends.nodes}
horizontal={false}
alwaysBounceVertical={true}
scrollEnabled
renderItem={({ item }) => (
<FriendItem friend={item} originatorId={data.me.id}/>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={NoFriendsContainer}
/>
Hope it helps. feel free for doubts
I am using React-Native-Paper's Menu Component
I am trying to show Menu item from the header after tapping an icon.
So far I have managed to show list of item on the screen only.
However, I want to show the menu list from the header.
Due to React Navigation's update from version:4.x to version:5.x, I am a bit confused on how to work this out. I tried following the example here but still I need some time to fully understand hook and the way it works.
All kinds of help would be appreciated.
Workable/Testable code link, code snippets and screenshots provided below:
Snack Link
Register.js:
import { TextInput, Button, Menu, Divider, Provider } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
class Register extends Component {
constructor(props) {
super(props);
this.state = {
visible: false,
}
}
//[ TEST DROP DOWN MENU ]
_openMenu = () => this.setState({ visible: true });
_closeMenu = () => this.setState({ visible: false });
renderMenuExample() {
return (
<View
style={{
paddingTop: 50,
flexDirection: 'row',
justifyContent: 'center'
}}>
<Menu
visible={this.state.visible}
onDismiss={this._closeMenu}
anchor={
< TouchableOpacity
onPress={this._openMenu}
style={{ marginHorizontal: 20 }}
>
<MaterialCommunityIcons name="earth" size={30} style={{ color: 'black' }} />
</TouchableOpacity>
}
>
<Menu.Item onPress={() => { }} title="Item 1" />
<Menu.Item onPress={() => { }} title="Item 2" />
<Divider />
<Menu.Item onPress={() => { }} title="Item 3" />
</Menu>
</View>
);
}
//[ TEST DROP DOWN MENU ]
render() {
return (
<Provider>
{this.renderMenuExample()}
</Provider>
);
}
}
export default Register;
App.js:
import { TextInput, Button, Menu, Divider, Provider } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import AntDesign from 'react-native-vector-icons/AntDesign';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Register"
component={Register}
options={{
headerBackImage: () => (
<AntDesign name="close" size={30} style={{ color: 'white' }} />
),
headerTitle: () => (
<View>
<Text style={{ flex: 1, fontSize: 20, fontWeight: 'bold', alignSelf: 'center', color: 'white' }}>
Register
</Text>
</View>
),
headerRight: () => (
<TouchableOpacity
onPress={() => {/* I WANT TO SHOW THE MENU HERE */ }}
style={{ marginHorizontal: 20 }}
>
<MaterialCommunityIcons name="earth" size={30} style={{ color: 'white' }} />
</TouchableOpacity>
),
headerStyle: {
backgroundColor: '#2e46ff',
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
Screenshot:
One possible solution would be to wrap the navigation container with a provider and have a separate component for the menu.
Tried this with your snack and it works
The code would be as below.
const CustomMenu = () => {
const [showMenu, setShowMenu] = React.useState(false);
return (
<View style={{}}>
<Menu
visible={showMenu}
onDismiss={() => setShowMenu(false)}
anchor={
<TouchableOpacity onPress={() => setShowMenu(true)}>
<MaterialCommunityIcons
name="earth"
size={30}
style={{ color: 'black' }}
/>
</TouchableOpacity>
}>
<Menu.Item onPress={() => {}} title="Item 1" />
<Menu.Item onPress={() => {}} title="Item 2" />
<Divider />
<Menu.Item onPress={() => {}} title="Item 3" />
</Menu>
</View>
);
};
function App() {
return (
<Provider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Register"
component={Register}
options={{
headerBackImage: () => (
<AntDesign name="close" size={30} style={{ color: 'white' }} />
),
headerTitle: () => (
<View>
<Text
style={{
flex: 1,
fontSize: 20,
fontWeight: 'bold',
alignSelf: 'center',
color: 'white',
}}>
Register
</Text>
</View>
),
headerRight: () => <CustomMenu />,
headerStyle: {
backgroundColor: '#2e46ff',
},
}}
/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
}