React Native 100% width view in scrollView - react-native

I have a horizontal ScrollView
In this ScrollView I want to display multiple Full height and width Views.
I don't figure out how to set each View's width to 100%.
Actually it like they have a "auto" width (about 70%)
<SafeAreaView style={styles.container}>
<ScrollView
style={styles.info}
horizontal={true}
>
{this.state.list.map(item => (
<View style={styles.item}>...</View>
))}
</ScrollView>
</SafeAreaView>
And the styles
info: {
width: "100%",
height: "100%",
display: "flex"
},
item: { // props for the items in my views
display: "flex",
alignItems: "center",
justifyContent: "space-between",
height: "100%",
paddingTop: 30,
paddingBottom: 10
}
I tried to put width : "100%" but of course it didn't work as excepted
Thanks

You would have to calculate the width of the device or container.
import { Dimensions } from 'react-native';
const screenWidth = Dimensions.get('window').width;

If you don't want the dimensions of the device because you'll have to convert the width value of your View you could you the contentContainerStyle props of ScrollView :
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
flexGrow: 1,
justifyContent: 'center',
width: '100%',
}}
>
{history.map((item, index) => (
<View
key={index}
style={{
height: '10%',
width: '60%',
backgroundColor: '#eee',
alignItems: 'center',
justifyContent: 'center'
}}>
<Text>
{ToDate(item.timestamp.seconds)[0]}
</Text>
</View>
))}
</ScrollView>
Hope this could help people out here !

Related

How to achieve drop-shadow with no blur in React Native

I'm new using React Native and I'm trying to map the following component (made in web) but for React Native with no success:
Elevation and shadow properties does not do the trick because they add some blur to the resulting shadow. Which would be the proper way to handle this?
Regards
Use react-native-cardview
import React, { Component } from 'react';
import {
View,
ScrollView,
TextInput,
} from 'react-native';
import CardView from 'react-native-cardview';
import styles from './styles';
export default class Signup extends Component {
render() {
return (
<View style={{ flex: 1, backgroundColor: colors.whiteColor }}>
<ScrollView contentContainerStyle={styles.signupContainer}>
<View style={styles.signupInputs}>
<CardView
style={styles.cardStyle}
cardElevation={2}
cardMaxElevation={2}
cornerRadius={5}
>
<TextInput
underlineColorAndroid="transparent"
style={[styles.signupInput, styles.commonsignupStyle]}
placeholder="Nom *"
placeholderTextColor={colors.primaryColor}
/>
</CardView>
<CardView
style={styles.cardStyle}
cardElevation={2}
cardMaxElevation={2}
cornerRadius={5}
>
<TextInput
underlineColorAndroid="transparent"
style={[styles.signupInput, styles.commonsignupStyle]}
placeholder="Prénom *"
placeholderTextColor={colors.primaryColor}
/>
</CardView>
</View>
</ScrollView>
</View>
);
}
}
Edit:
For dynamic height, two lines or more of text, as asked for in the comments, I had to use another workaround.
https://snack.expo.io/7bVXvbmE0
const Label = () => {
return <View style={{width: 100, height: 50}}>
<View style={styles.topView}>
<Text>Hello world</Text>
<Text>Hi world</Text>
</View>
<View style={styles.shadowView} >
<Text style={{color: 'transparent'}}>Hello world</Text>
<Text style={{color: 'transparent'}}>Hi world</Text>
</View>
</View>;
}
Whatever dynamic text you have on the label, duplicate for the shadow label, but make it transparent. That way you are guaranteed that the shadow follows the top view.
Also, get rid of the hardcoded heights in the styles. For both top view and shadow view, their heights are informed by the text input, and the wrapper container's height is informed by the two views.
Lastly, change shadow view style's top to be just a few points above 0 to make sure you it peeks from under topview. You can adjust borderRadius of the shadow view to fit your preferences.
const styles = StyleSheet.create({
topView: {
width: '100%',
position: 'absolute',
top: 0, backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 25,
},
shadowView: {
position: 'absolute',
top: 3,
width: '100%',
zIndex: -10,
borderRadius: 17,
backgroundColor: '#ddd'}
});
Previous Post
A little bit hacky, but you can do this if you absolutely don't want any blur.
https://snack.expo.io/pWyPplcm3
const Label = () => {
return <View style={{width: 100, height: 30}}>
<View style={styles.topView}>
<Text>Hello world</Text>
</View>
<View style={styles.shadowView} />
</View>;
}
styles:
const styles = StyleSheet.create({
topView: {
height: 25,
width: '100%',
position: 'absolute',
top: 0, backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 15,
},
shadowView: {
position: 'absolute',
top: 0,
height: 28,
width: '100%',
zIndex: -10,
borderRadius: 13,
backgroundColor: '#ddd'}
});

Why are my buttons running off the screen?

I'm trying to have my two buttons sit in a row, equally spaced, and I want them of equal height and width. But they look like this at the moment.
I'm very new to React Native so please go gently!
Here's my code for what's returned.
return (
<View style={styles.screen}>
<View style={styles.horseProfile}>
<HorseProfile />
</View>
<View style={styles.vitalSignsGrid}>
<LargeVitalSigns />
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={this._alertHandler}>
<View style={styles.buttonStyling}>
<Text style={styles.buttonText}>ECG</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this._alertHandler}>
<View style={styles.buttonStyling}>
<Text style={styles.buttonText}>Resp Pattern</Text>
</View>
</TouchableOpacity>
</View>
<View>{/* timer and stop button */}</View>
</View>
)
Here are my styles.
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
horsePatientProfile: {
flex: 1
},
vitalSignsGrid: {
flex: 3,
backgroundColor: '#14172B'
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'green',
width: '100%',
flex: 4
},
buttonStyling: {
backgroundColor: '#2B4250',
borderRadius: 30,
alignItems: 'center',
justifyContent: 'space-around',
width: '50%',
height: '35%',
flexDirection: 'row',
},
buttonText: {
color: '#84C5C6',
fontWeight: 'bold'
}
})
Can anyone help please? Thank you.
the width of your buttons styles.buttonStyling is 50% which is 50% of the parent Component, the parent is the touchableOpacity, since it doesn't have a set width itself it will stretch with the content, in other words the 50% does not mean the same thing, you should give an exact (relative size, I like react-native-size-matter) to the touchable opacity and justifyContent as space between to space evenly
For height, width try using React Native Dimensions React Native Dimentions
Import it:
import {Dimensions} from "react-native";
var {height, width} = Dimensions.get('window');
Example using in style:
buttonStyling: {
backgroundColor: '#2B4250',
borderRadius: 30,
alignItems: 'center',
justifyContent: 'space-around',
width: width/2,
height: height / 3.5,
flexDirection: 'row',
},
or use Flexbox

How to prevent react native modal from moving up when keyboard opens in android?

I have a very basic modal component(using React-native-modal) which render its given child views. However, I dont want the behaviour similar to KeyBoardAvoiding view, i.e. I don't want the modal to be pushed up when keyboard opens.
<Modal
isVisible={isVisible}
onBackdropPress={onCartDismiss}
style={CartStyles.cartModal}
onSwipeEnd={this.onCartDismiss}
onSwipe={this.onCartDismiss}
swipeDirection="down"
swipeThreshold={200}
propagateSwipe
avoidKeyboard={false}
>
{this.props.children}
....
On ios it is working fine i.e. the keyboard opens over the modal component, but not on android. avoidKeyboard={false} is not working.
This is my style for the modal (position:'absolute' didn't work too)
cartModal: {
position: 'absolute',
justifyContent: 'flex-end',
bottom: 0,
left: 0,
right: 0,
zIndex: 1,
},
I have even tried changing softinputmode in android manifest to :
android:windowSoftInputMode="adjustPan"
<Modal
isVisible={modalVisible}
animationInTiming={500}
animationOutTiming={1000}
backdropTransitionInTiming={500}
backdropTransitionOutTiming={1000}
onBackdropPress={() => setModalVisible(!modalVisible)}
onBackButtonPress={() => setModalVisible(!modalVisible)}
style={{
justifyContent: 'flex-end',
margin: 0,
position:'absolute'
}}
avoidKeyboard={false}
>
try this, it works for me.
Set you model height as integer value without percentage.
<Modal
// style={{backgroundColor:'red'}}
deviceHeight={screenHeight}
deviceWidth={screenWidth}
transparent={true} visible={isVisible} animated={false}>
<View style={{
backgroundColor: 'rgba(0,0,0,.6)',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<View style={{
flexDirection: 'row',
height: 200,
width: '80%',
alignSelf: 'center'
}}>
{content}
</View>
</View>
</Modal>
Give the main view inside your modal a "fixed height value" and the containing view should have a "100%" view height. Like this:
<Modal animationType={fade} ...>
<View style={{
height: "100%",
width: "100%",
alignItems: "center",
// justifyContent: "center",
backgroundColor: "rgba(0, 0, 0, 0.4)",
}}>
<View style={{
borderRadius: 10,
marginHorizontal: width * 0.05,
marginTop: height * 0.1,
width: width * 0.9
height: height * 0.8
}}>
...`enter code here`
</View>
</View>
</Modal>
I solved the issue by removing justifyContent: "center"

react native scrollView Height always stays static and does not change

I build react native app and I use with scrollView for header with list of text horizontal.
The issue is that the height of the scroll view takes half size of the screen. Even after declared it as a style, it still stays as it is.
screen with the scrollView
<View style={Style.container} >
{this.props.ExtendedNavigationStore.HeaderTitle ? <BackHeader header={this.props.ExtendedNavigationStore.HeaderTitle} onPressBack={this.goBack} /> : <Header openDrawer={this.openDrawer} />}
<ScrollView contentContainerStyle={{flexGrow:1}} style={Style.scrollableView} horizontal showsHorizontalScrollIndicator={false}>
{this.renderScrollableHeader()}
</ScrollView>
<Routes /> /* stack with dashboard screen */
</View>
</Drawer>
)
}
styles
import {StyleSheet} from 'react-native'
import {calcSize} from '../../utils'
const Styles = StyleSheet.create({
container : {
flex:1,
backgroundColor:"#e9e7e8"
},
scrollableView:{
height: calcSize(40),
backgroundColor: '#000',
},
textCategory:{
fontSize: calcSize(25),
color:'#fff'
},
scrollableButton:{
flex:1,
margin:calcSize(30)
}
})
export default Styles
As you can see the black size is the scroll View,
I want it to be small.
In routes stack into dashboard screen, the style:
const Style = StyleSheet.create({
container: {
backgroundColor: '#9BC53D',
flex: 1,
justifyContent: 'space-around',
alignItems: 'center'
},
text: {
fontSize: 35,
color: 'white',
margin: 10,
backgroundColor: 'transparent'
},
button: {
width: 100,
height: 75,
margin: 20,
borderWidth: 2,
borderColor: "#ecebeb",
justifyContent: "center",
alignItems: "center",
borderRadius: 40
}
})
There is an existing limitation with ScrollView where height cannot be provided directly.
Wrap the ScrollView in another View and give height to that View.
Like,
render() {
return (
<View style={styles.container}>
<View style={{height: 80}} >
<ScrollView
horizontal
style={{ backgroundColor: 'blue'}}
>
<Text style={{padding: 24}} >title1</Text>
<Text style={{padding: 24}} >title2</Text>
<Text style={{padding: 24}} >title3</Text>
<Text style={{padding: 24}} >title4</Text>
<Text style={{padding: 24}} >title5</Text>
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
snack sample: https://snack.expo.io/HkVDBhJoz
EXTRAS: Unlike height providing width to a ScrollView will work correctly
Use flexGrow:0 inside ScrollView style
<ScrollView style={{ flexGrow:0 }}>
That worked for me:
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ flexGrow: 1 }}>
...
</View>
</ScrollView>
Considering the issue that you are using fixed height for the header, and flex for the Routes maybe, the orientation for different devices would not scale well and would look weird.
Therefore you may consider switching it to the flex
Here is the example by adding flexGrow to the styles of the ScrollView since it accepts view props
<View style={{ flex: 1 }}>
<ScrollView style={{ flexGrow: 0.05, backgroundColor: 'red', paddingTop: 50 }} horizontal>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
</ScrollView>
<View style={{ flex: 0.95, backgroundColor: 'green' }} />
</View>
and here's the link to the snack expo
Use maxHeight inside scrollview style
<ScrollView style={{ maxHeight: 40 }}>•••</ScrollView>
Setting minHeight: int, maxHeight: int to ScrollView should work where int is height in pixels.
example below
<ScrollView style={{ minHeight: 280, maxHeight: 260}}>

react-native style opacity for parent and child

react-native : I have one View and the child of View is an Image , I applied opacity: 0.5 for View and opacity: 0.9 for an Image but it doesn't apply for Image ,the parent opacity is applying for child , the child doesn't take independent opacity
Try changing the opacity using alpha-value of the background color instead. Then it should be possible applying different opacities for children.
For example:
<View style={{backgroundColor: 'rgba(0,0,0,0.5)'}}/>
React-Native 0.60+
There is a new opacity prop that you can pass in:
<View style={{opacity: 0.5}} />
React-Native 0.59.x and lower
Like this (with 50% at the end of color hash):
<View style={{backgroundColor: '#FFFFFF50'}} />
Or RGBa way:
<View style={{backgroundColor: 'rgba(0,0,0,0.5)'}} />
In react-native 0.6, you can use the opacity prop on a View. Example:
<View opacity={1.0} />
<View opacity={0.5} />
1.0 = opaque (alpha == 1.0)
0.0 = clear (alpha == 0.0)
See https://facebook.github.io/react-native/docs/0.6/view-style-props#opacity
Snack: https://snack.expo.io/S1KjXqe6N
If you want to display some text with transparent alpha opacity then I have the best way, just try.
TransparentBG:{
backgroundColor: '#00000070',
color:'#FFFFFF'
}
here, "70" indicates opacity %.
-Thanks
You need to use needsOffscreenAlphaCompositing like this-
<View needsOffscreenAlphaCompositing>
...
<View/>
If you want to change the opacity of a view that doesn't recognize the opacity prop (such as a TouchableOpacity), wrap it in a View first and change the opacity prop of that.
<View opacity={0.3}>
<TouchableOpacity>
</TouchableOpacity>
</View>
You can't change parent opacity without affecting child, so you should have absolute positioned background. For proper child positioning, you should add an additional container. Check out this snack: snack.expo.io/SkaHLjzr8
...
<View style={styles.container}>
<View style={styles.card} >
<View style={styles.background} />
<View style={styles.imageContainer}>
<Image style={styles.image} source="..." />
</View>
</View>
</View>
...
...
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
background: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'blue',
opacity: .5,
zIndex: 1,
},
card: {
height: 400,
},
imageContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: 'center',
alignItems: 'center',
zIndex: 2,
opacity: 0.8,
},
image: {
width: 200,
height: 200
}
...
HACK FOR BACKGROUNDS OPACITY
Use combination of 2 backgroundColor in order to imitate the opacity
After playing sometimes and be lost on the internet to find a simple solucion, I realized that at the current React-Native Version V 0.64 the opacity for the backgrounds, at least as it is commonly used for Web Dev just is not suited for React-Native.
APP
Use ImageBackground Component --> DOCS:
Set you background image on the ImageBackground
import React from 'react';
import { ImageBackground, View, Text, StyleSheet, ScrollView} from 'react-native';
const App = () => {
return (
<ImageBackground style={ mainStyle.background } source={ { uri: "https://reactjs.org/logo-og.png" } } resizeMode="cover">
<ScrollView style={ mainStyle.overlay }> // Here its style will be used as opacity
<View style={ mainStyle.containerCenter}>
<View style={ mainStyle.homeTitleWraper}>
<Text style={ mainStyle.homeTitle }> Hello WOrld</Text>
</View>
</View>
</ScrollView>
</ImageBackground>
);};
export default App;
Style
Style, Here the First Child of the Background has to take the whole
screen size, with style overlay it will lay down like a thin blanket on top of the Background, imitating the opacity.
const mainStyle = StyleSheet.create({
background: {
width: "100%",
height: "100%",
},
overlay: {
backgroundColor: 'rgba(255, 255, 255, .5)' // HERE USE THE LAST DIGIT AS IF IT WERE OPACITY
},
containerCenter : {
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
paddingHorizontal: 30,
marginVertical: 60,
},
homeTitleWraper: {
paddingHorizontal: 40,
paddingVertical: 100,
},
homeTitle: {
fontSize: 40,
fontWeight: "900",
textAlign: "center",
textTransform: "uppercase",
color: "white",
fontStyle: "italic",
},
containerSmall: {
marginVertical: 10,
width: "100%"
}