I am trying to accomplish that the action button stays visible all the time. Once the user tabs on it, a modal appears and of course, the action button stays behind the modal.
I tried:
Using Portals
Create another button inside the modal (independent as the original one) but this causes problems depending on the device, and the user can see the transition from one button to another.
tried this pre-made one but can't seem to put it on tabbar correctly:actionbutton
My approach
MY CODE
import React, {useState} from 'react';
import {
Dimensions,
Platform,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import Modal from 'react-native-modal';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import Feather from 'react-native-vector-icons/Feather';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import TabBg from '../svg/TabBg';
import colors from './../utils/colors';
const {width, height} = Dimensions.get('window');
Platform.OS == 'ios'
? console.log('ios HEIGHT: ' + height + ' WIDTH: ' + width)
: console.log('android HEIGHT: ' + height + ' WIDTH: ' + width);
Ionicons.loadFont();
Feather.loadFont();
AntDesign.loadFont();
Entypo.loadFont();
MaterialIcons.loadFont();
const TabBarAdvancedButton = ({bgColor, ...props}) => {
const [modalVisible, setModalVisible] = useState(false);
return (
<>
<View style={styles.container} pointerEvents="box-none">
<TabBg color={'white'} style={styles.background} />
<TouchableOpacity
style={styles.button}
onPress={props.onPress}
activeOpacity={0.9}
onPress={() => setModalVisible(true)}>
<Entypo name="plus" style={styles.buttonIcon} />
</TouchableOpacity>
</View>
<Modal
backdropOpacity={0.8}
animationIn="fadeIn"
animationOut="fadeOut"
isVisible={modalVisible}
onBackdropPress={() => setModalVisible(false)}
style={styles.contentView}>
{/*close button */}
<View style={styles.content}>
<TouchableOpacity
style={{
position: 'absolute',
backgroundColor: 'red',
alignSelf: 'center',
}}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-around',
marginBottom: height * 0.02,
}}>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} style={[styles.buttonItem]}>
<MaterialIcons name="fitness-center" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
</View>
</View>
</Modal>
</>
);
};
export default TabBarAdvancedButton;
const styles = StyleSheet.create({
container: {
position: 'relative',
width: 75,
alignItems: 'center',
},
background: {
position: 'absolute',
top: 0,
},
button: {
top: -22.5,
justifyContent: 'center',
alignItems: 'center',
width: 50,
height: 50,
borderRadius: 27,
backgroundColor: colors.PRIMARY_COLOR_DARK,
},
buttonIcon: {
fontSize: 16,
color: '#F6F7EB',
},
content: {
backgroundColor: 'transparent',
padding: 60,
justifyContent: 'space-evenly',
alignItems: 'center',
borderTopRightRadius: 17,
borderTopLeftRadius: 17,
flexDirection: 'row',
},
contentTitle: {
fontSize: 20,
marginBottom: 12,
},
contentView: {
justifyContent: 'flex-end',
margin: 0,
},
buttonStyle: {
height: 50,
width: 50,
borderRadius: 100,
},
buttonStyle2: {
height: 50,
width: 50,
borderRadius: 100,
},
buttonItem: {
height: 56,
width: 56,
borderRadius: 100,
borderColor: '#468CFF',
borderWidth: 3.5,
backgroundColor: '#366ABF',
bottom: 50,
justifyContent: 'center',
alignItems: 'center',
},
});
Related
I am coding a project using expo react native and I made a horizontal scrollview for images. The images are styled correctly when pixels are used: <Image code... style={{width: 350}}/> However if I try to change the 350 to 35% the image disappears from the screen. I have tried several different ways to fix this problem, like adding a 100% width viewport for the parent class (like seen below), however it still is not working.
Here is the file of code:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image, ScrollView, Modal, Pressable } from 'react-native';
import tw from 'tailwind-react-native-classnames';
import { useState } from 'react';
export default function ImpEvents() {
const slides = ['https://patch.com/img/cdn20/users/22844250/20200421/014148/styles/patch_image/public/livingston-highschool-schoolpr___21133742706.jpg', 'https://patch.com/img/cdn/users/22844250/2015/05/raw/20150555523bf088bd6.jpg', 'https://patch.com/img/cdn/users/22821264/2014/08/raw/5400e8ea02f3c.png']
const [modalVisible1, setModalVisible1] = useState(false);
const [modalVisible2, setModalVisible2] = useState(false);
const [modalVisible3, setModalVisible3] = useState(false);
return (
<View style={{width: '100%'}}>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible1}
onRequestClose={() => {
setModalVisible1(!modalVisible1);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>1</Text>
</Modal>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible2}
onRequestClose={() => {
setModalVisible2(!modalVisible2);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>2</Text>
</Modal>
<Modal
animationType="slide"
presentationStyle='pageSheet'
visible={modalVisible3}
onRequestClose={() => {
setModalVisible3(!modalVisible3);
}}>
<View style={{ position: 'absolute', backgroundColor: 'grey', top: 10, alignContent: 'center', height: 5, width: '10%', alignSelf: 'center', borderRadius: 10 }}>
</View>
<Text style={{ fontSize: 80, alignSelf: 'center' }}>3</Text>
</Modal>
<Text style={{ left: 40, fontFamily: 'OpenSans_700Bold', marginTop: '70%', fontSize: 25, color: "#3D3D3D" }}>Important Information</Text>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 10 }}>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={{ paddingTop: 7, paddingLeft: 40 }} snapToInterval={370} decelerationRate={0}>
<Pressable onPress={() => setModalVisible1(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[0]
}}
style={{ width: "35%", height: 175, borderRadius: 10 }}
/>
</Pressable>
<Pressable onPress={() => setModalVisible2(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[1]
}}
style={{ width: 350, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</Pressable>
<Pressable onPress={() => setModalVisible3(true)} style={({ pressed }) => [
{
opacity: pressed
? '0.5'
: '1'
},
]}>
<Image
source={{
uri: slides[2]
}}
style={{ width: 350, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</Pressable>
<View
style={{ width: 50, height: 175, borderRadius: 10, marginLeft: 20 }}
/>
</ScrollView >
</View>
<View/>
)
}
So the image at index 0 is not being displayed but the images at indices 1 and 2 are being displayed when I don't use percentages.
Thanks for the help.
If you would like to use % you need to give a parent component width. Or there is another solution which you can get the width of the device in react native. You can achieve it using Dimension as below:
import { Dimensions } from 'react-native';
const ScreenWidth = Dimensions.get('window').width;
So in order to give 90% width of device you can use it like this width: ScreenWidth * 0.9.
It's Happening because Its parent component <Pressable> does not have the width style mentioned if you want to provide dynamic height or width in percentage then you must provide height and width to its parent component.
just give width: "100%" to its parent component and then check and if that does not work check the parent component of the parent component and backtrace it.
How can i style to make both the buttons at the bottom of the screen and make a little gap between them and how can i make my profile image at the top of the screen and text below it like this image https://www.figma.com/file/BGDDg26x9Cl5AAOA2GGg52/Untitled?t=JCVgnCTjHVkRyhPX-0
i tried to style but something than the profile image and text gets hidden
import { StyleSheet, Text, View, Image } from 'react-native'
const App = () => {
return (
<View style={styles.container}>
<View style={styles.userSection}>
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={('./img.jpg')
resizeMode="contain"
overflow="hidden"
/>
</View>
<Text style={styles.text}}>Text</Text>
</View>
})
}
<View style={styles.interacte}>
<Text style={formbtn}>Button 1</Text>
<Text style={formbtn}>Button 2</Text>
</View>
</View>
)
}
export default App
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},
userSection: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 80
},
imageContainer: {
width: 150,
height: 150,
borderRadius: 80,
overflow: 'hidden',
marginRight: -160,
marginTop: -600
},
image: {
width: '100%',
height: '100%',
},
text: {
color: 'white',
fontSize: 20,
fontWeight: 'bold',
marginTop: -350,
},
interacte: {
marginTop: 500,
position: absolute,
}
});
App.js
import React from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
const App = () => {
return (
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<View style={{ marginTop: 10, marginBottom: 30 }}>
<Image
style={{ width: 100, height: 100, borderRadius: 20 }}
source={{
uri: 'https://cdn-icons-png.flaticon.com/128/919/919851.png',
}}
/>
</View>
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>Welcome to world</Text>
<View style={{ marginTop: 300 }}>
<TouchableOpacity
style={{
width: 200,
height: 50,
backgroundColor: '#000',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 10,
}}>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold' }}>
Sing In
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
width: 200,
height: 50,
backgroundColor: '#000',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold' }}>
Sing Up
</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default App;
output
Hope this will help you!!🐼
I want to add a clock to my component right-bottom here is my code :
import React from "react";
import { StyleSheet, View, Image, Text } from "react-native";
import CircleCard from "./CircleCard";
import { MaterialIcons } from "#expo/vector-icons";
export default function ChatCard() {
return (
<View style={styles.container}>
<View>
<CircleCard />{// my component}
</View>
<View
style={{
flexDirection: "row",
flex: 1,
flexWrap: "wrap",
flexShrink: 1,
}}
>
<Text style={{ color: "gray" }} numberOfLines={1}>{//For parsing }
SomeRandomLettersSomeRandomLettersSomeRandomLettersSomeRandomLetters {//The message part}
</Text>
<Text style={{ position: "absolute", bottom: 0, right: 0 }}>18:48</Text> {//The clock bottom right}
</View>
<View style={{ margin: 15 }}> {//For Icon}
<MaterialIcons
name="keyboard-arrow-right"
size={40}
color="black"
style={{ width: 30 }}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
width: "100%",
height: 80,
margin: 5,
flexDirection: "row",
flexWrap: "wrap",
borderColor: "gray",
borderWidth: 1,
borderRadius: 20,
justifyContent: "space-between",
},
});
i added it at the end but now the First and Second Text overlaped.
Also an image for my goal:
Note2 : I read that the position absolute violate the flex-box but i do not find any style for moving the Text component to end. If there is an other way. i will be glad.
I don't know if it is what you want actually but here is my solution:
import React from "react";
import { StyleSheet, View, Image, Text, Dimensions } from "react-native";
import { MaterialIcons } from "#expo/vector-icons";
export default function ChatCard() {
return (
<View style={styles.container}>
<View style={styles.image}>
<Text style={{ fontSize: 34 }}>B</Text>
</View>
<View
style={styles.rowContent}
>
<Text style={styles.longText} ellipsizeMode='tail' numberOfLines={1}>
SomeRandomLettersSomeRandomLettersSomeRandomLettersSomeRandomLetters
</Text>
<Text style={styles.time}>18:48</Text>
</View>
<View style={{ margin: 15 }}>
<MaterialIcons
name="keyboard-arrow-right"
size={40}
color="black"
style={{ width: 30 }}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 30,
width: '100%',
height: 80,
margin: 5,
flexDirection: "row",
borderColor: "gray",
borderWidth: 1,
borderRadius: 20,
},
image: {
alignItems: 'center',
justifyContent: "center",
width: 70,
padding: 10,
},
rowContent: {
justifyContent: "center",
alignItems: "center",
flexDirection: 'column',
flex: 1
},
longText: {
color: "gray",
alignSelf: 'stretch',
justifyContent: 'center'
},
time: { alignSelf: 'flex-end' }
});
I am trying to make an Action Button on the tapbar which deploys multiple items using Modal. The issue I have is that I want the action button to stay visible so the user can toggle between the modal.
Here you can see the action button visible
obviously disappears once the modal is activated.
Tried:
On the modal make another button, but on different device sizes the button moves.
Code
import React, {useState} from 'react';
import {
Dimensions,
Platform,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import Modal from 'react-native-modal';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Entypo from 'react-native-vector-icons/Entypo';
import Feather from 'react-native-vector-icons/Feather';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import TabBg from '../svg/TabBg';
import colors from './../utils/colors';
const {width, height} = Dimensions.get('window');
Platform.OS == 'ios'
? console.log('ios HEIGHT: ' + height + ' WIDTH: ' + width)
: console.log('android HEIGHT: ' + height + ' WIDTH: ' + width);
Ionicons.loadFont();
Feather.loadFont();
AntDesign.loadFont();
Entypo.loadFont();
MaterialIcons.loadFont();
const TabBarAdvancedButton = ({bgColor, ...props}) => {
const [modalVisible, setModalVisible] = useState(false);
return (
<>
<View style={styles.container} pointerEvents="box-none">
<TabBg color={'white'} style={styles.background} />
<TouchableOpacity
style={styles.button}
onPress={props.onPress}
activeOpacity={0.9}
onPress={() => setModalVisible(true)}>
<Entypo name="plus" style={styles.buttonIcon} />
</TouchableOpacity>
</View>
<Modal
backdropOpacity={0.8}
animationIn="fadeIn"
animationOut="fadeOut"
isVisible={modalVisible}
onBackdropPress={() => setModalVisible(false)}
style={styles.contentView}>
{/*close button */}
<View style={styles.content}>
<TouchableOpacity
style={{
position: 'absolute',
backgroundColor: 'red',
alignSelf: 'center',
}}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-around',
marginBottom: height * 0.02,
}}>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} style={[styles.buttonItem]}>
<MaterialIcons name="fitness-center" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
</View>
</View>
</Modal>
</>
);
};
export default TabBarAdvancedButton;
const styles = StyleSheet.create({
container: {
position: 'relative',
width: 75,
alignItems: 'center',
},
background: {
position: 'absolute',
top: 0,
},
button: {
top: -22.5,
justifyContent: 'center',
alignItems: 'center',
width: 50,
height: 50,
borderRadius: 27,
backgroundColor: colors.PRIMARY_COLOR_DARK,
},
buttonIcon: {
fontSize: 16,
color: '#F6F7EB',
},
content: {
backgroundColor: 'transparent',
padding: 60,
justifyContent: 'space-evenly',
alignItems: 'center',
borderTopRightRadius: 17,
borderTopLeftRadius: 17,
flexDirection: 'row',
},
contentTitle: {
fontSize: 20,
marginBottom: 12,
},
contentView: {
justifyContent: 'flex-end',
margin: 0,
},
buttonStyle: {
height: 50,
width: 50,
borderRadius: 100,
},
buttonStyle2: {
height: 50,
width: 50,
borderRadius: 100,
},
buttonItem: {
height: 56,
width: 56,
borderRadius: 100,
borderColor: '#468CFF',
borderWidth: 3.5,
backgroundColor: '#366ABF',
bottom: 50,
justifyContent: 'center',
alignItems: 'center',
},
});
You can try the below code, you should be adding the action button inside the modal as well, so that will be displayed inside modal.
export default ActionButton = () => {
const [modalVisible, setModalVisible] = useState(false);
return (
<>
<Button
onPress={() => {
setModalVisible(true);
}}
buttonStyle={styles.buttonStyle}
icon={
<Entypo
name={"plus"}
fill={Colors.tintColor}
color={Colors.iconColor}
/>
}
/>
<View style={styles.container}>
<Modal
backdropOpacity={0.8}
isVisible={modalVisible}
onBackdropPress={() => setModalVisible(false)}
style={styles.contentView}
>
{/*close button */}
<View style={styles.content}>
<View
style={{
flexDirection: "row",
flex: 1,
justifyContent: "space-around",
}}
>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.8}
style={[styles.buttonItem, { bottom: 130 }]}
>
<MaterialIcons name="fitness-center" size={20} color="#fff" />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} style={styles.buttonItem}>
<AntDesign name="search1" size={20} color="#fff" />
</TouchableOpacity>
<Button
onPress={() => {
setModalVisible(true);
}}
buttonStyle={styles.buttonStyle}
icon={
<Entypo
name={"plus"}
fill={Colors.tintColor}
color={Colors.iconColor}
/>
}
/>
</View>
</View>
</Modal>
</View>
</>
);
};
const styles = StyleSheet.create({
content: {
backgroundColor: "transparent",
padding: 60,
justifyContent: "space-evenly",
alignItems: "center",
borderTopRightRadius: 17,
borderTopLeftRadius: 17,
flexDirection: "row",
},
contentTitle: {
fontSize: 20,
marginBottom: 12,
},
contentView: {
justifyContent: "flex-end",
margin: 0,
},
buttonStyle: {
height: 50,
width: 50,
backgroundColor: Colors.tintColor,
borderRadius: 100,
},
buttonStyle2: {
height: 50,
width: 50,
backgroundColor: Colors.tintColor,
borderRadius: 100,
},
buttonItem: {
height: 56,
width: 56,
borderRadius: 100,
borderColor: "#468CFF",
borderWidth: 3.5,
backgroundColor: "#366ABF",
bottom: 50,
justifyContent: "center",
alignItems: "center",
},
});
there some issue while i try to push the TouchableOpacity button coz its not let me press it and also after i press it so i need to see the time picker and choose a time as i want and its shuold be display inside the square view in the middle.
what is the way to do it coz i got stacked right now.
I add picture of the screen :
import React, { useState } from 'react';
import { Text, View, Button, Platform, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
import { useRoute, useNavigation } from '#react-navigation/native';
import DateTimePicker from '#react-native-community/datetimepicker';
import Icon from 'react-native-ionicons';
function NetuneyDigum() {
const [date, setDate] = useState(new Date());
const [mode, setMode] = useState('time');
const [show, setShow] = useState(false);
const onChange = (event, selectedDate) => {
setShow(Platform.OS === 'ios');
};
const showMode = (currentMode) => {
setShow(true);
setMode(currentMode);
};
const showTimepicker = () => {
showMode('time');
};
return (
<>
<View
style={{
flex: 1,
alignItems: 'center',
backgroundColor: '#cbced4',
}}
>
<View
style={{
paddingTop: 30,
flexDirection: 'row',
justifyContent: 'space-evenly',
paddingRight: 50,
right: 30,
}}
>
<View
style={{
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-evenly',
paddingRight: 10,
}}
>
<Text style={{ fontWeight: 'bold', fontSize: 18, color: 'black' }}>
THE TIME IS :
</Text>
</View>
<View
style={{
height: 50,
width: 100,
borderRadius: 5,
borderColor: 'black',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
// left: 40,
}}
>
<Text
style={{
fontSize: 20,
fontWeight: 'bold',
color: '#368fc7',
paddingLeft: 10,
}}
>
{show}
</Text>
<TouchableOpacity
onPress={showTimepicker}
style={{
height: 60,
width: 60,
borderRadius: 5,
borderColor: 'black',
borderWidth: 2,
left: 100,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Icon name="md-time" size={50} color="black" />
</TouchableOpacity>
</View>
</View>
{show && (
<DateTimePicker
testID="dateTimePicker"
value={date}
mode={mode}
is24Hour={true}
display="default"
onChange={onChange}
/>
)}
</View>
</>
);
}
you wrong in TouchableOpacity position in code and bad way to styling , set left attribute to zero and move your TouchableOpacity outside of current parent
<View
style={{
paddingTop: 30,
flexDirection: 'row',
justifyContent: 'space-evenly',
paddingRight: 50,
right: 30,
}}
>
<View
style={{
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-evenly',
paddingRight: 10,
}}
>
<Text style={{ fontWeight: 'bold', fontSize: 18, color: 'black' }}>
THE TIME IS :
</Text>
</View>
<View
style={{
height: 50,
width: 100,
borderRadius: 5,
borderColor: 'black',
borderWidth: 2,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
// left: 40,
}}
>
<Text
style={{
fontSize: 20,
fontWeight: 'bold',
color: '#368fc7',
paddingLeft: 10,
}}
>
{show}
</Text>
</View>
//move touchable opacity here
<TouchableOpacity
onPress={showTimepicker}
style={{
height: 60,
width: 60,
borderRadius: 5,
borderColor: 'black',
borderWidth: 2,
//left: 100, remove this line
justifyContent: 'center',
alignItems: 'center',
}}
>
<Icon name="md-time" size={50} color="black" />
</TouchableOpacity>
</View>