width: '100%' vs Dimension.get('window').width in react native - react-native

I'm new to react native and css styling as a whole so sorry if the question is very basic. I want a view to take 100% of the available screen width and when i use the code below my view seems to go outside the screen boundry, though when I use Dimension.get('window').width it work just fine. can someone explain how they differ from each other. any help would be really appreciated. thanks
return(
<TouchableOpacity style = {styles.food_wrapper}
onPress = {()=> this.userAction()}
>
<Text style = {styles.foodname}>
{this.name}
</Text>
<Text style = {styles.foodprice}>
Rs: {this.price}
</Text>
</TouchableOpacity>
);
food_wrapper:{
flex: 1,
flexDirection :'row',
justifyContent:'space-between',
alignItems:'flex-start',
width: '100%',//Dimensions.get('window').width,
minHeight: 50,
marginVertical: '1%',
padding: '2%',
backgroundColor: 'rgb(155,200,200)'
},

You need to understand what is the basic difference from 100% and the width you get using dimension.get('window')
100% means you want to get the container 100% width which mean if your parent container is 50px then 100% will return 50px.
the width from dimension give you a static width of your device width
so be careful to choose what to use to your component
if you want to follow the parent container then it is easier to use 100% then width from dimension but for responsive reasons without any parent container or it is the parent itself then width from dimension will work better

You need to add a wrapper view with flexDirection: 'row', then style the child view (or Touchable or whatever) with flex: 1
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1, height: 100, backgroundColor: 'grey' }} />
</View>
Or you could use alignSelf: 'stretch' inside a few with flexDirection: 'column' (which is the default for all views)
Hang in there. Learning flexbox takes some practice. Your first thought when you get stuck should be "do I need to add a wrapper view?"

Related

Use space-around without setting height value

I want to put 3 texts on the screen one on the top, one on the middle an one on the bottom. For this I thought about using the space-around property. This is my code
<Screen style={styles.container} backgroundColor={color.transparent}>
<View style={styles.playerContainer}>
<View><Text>text 1</Text></View>
<View><Text>text 2</Text></View>
<View><Text>text 3</Text></View>
</View>
</Screen>
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'blue'
},
playerContainer:{
flexDirection: 'column',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'red',
}
});
This is not working as expected. It looks better is I set a height for playerContainer, but I am enable to calculate the right hight because of the navigation bar etc.. I just need to add three text in the container. I must calculate the hight of playerContainer or I am doing something wrong?
If you want the first entry to be at the start of the container, the second to be at the center, and the last to be at the end, you need justifyContent: 'space-between'. I found this article helpful when learning about flex in React Native https://blog.reactnativecoach.com/understanding-flex-in-react-native-b34dfb4b16d1

scrollview and flatlist override loading view

I have got flatlist inside scrollview and its working fine, but both going over the loading view so I got blank view while first loading which contain both of them while first run loading.
I didn't find any questions on it.
<ScrollView style={{ backgroundColor: 'white', padding: scale(5) }} contentContainerStyle={{}}
// scrollEventThrottle={this.onScroll}
>
<FlatList style={{ transform: [{ scaleX: -1 }], borderBottomWidth:1, borderBottomColor: '#eee'}} contentContainerStyle={{ justifyContent: 'center', paddingBottom: !dataFollowing ? scale(40) : scale(20), alignItems: 'flex-start', backgroundColor: 'white', paddingHorizontal: scale(10) }} horizontal data={allData}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
ListHeaderComponent={
<TouchableOpacity onPress={() => {
this.props.navigation.navigate('Search');
}}>
</FlatList></ScrollView>
so basically I see this
scrollview over loading
As per i worked with this, i figured out that there is no need to use ScrollView as FlatList is Scrollable . If you are using FlatList inside ScrollView then it throw some warning.
This also happened same with me while using Loader with them so try :
Create a state and give boolean value and in the render you would create tenrary condition (?:) .
For example data is coming from API , so if data is not fetched the isLoading state is true and Loader is running and as soon as data is fetched then setState isLoading to false and Flatlist data is rendering.
If it doesn't clear or not matched with your question then please try to elaborate more i will help surely.

react-native-keyboard-aware-scroll-view : Page scrolls down when I start typing

Until typing everything is ok. However after starting typing page scrolls down(shifting). I am not able to solve this whatever i do...
<ImageBackground
source={bgSrc}
style={styles.background}
resizeMode="cover">
<StatusBar hidden={true} />
<KeyboardAwareScrollView
showsVerticalScrollIndicator={false}
enableOnAndroid
>
{screenToShow}
</KeyboardAwareScrollView>
</ImageBackground>
const styles = StyleSheet.create({
container: {
width: '100%',
height: height,
backgroundColor: '#555',
},
background: {
flex: 1,
width: null,
height: null,
justifyContent: 'center',
alignItems: 'center'
}
});
before typing, it's looking perfect
After typing in the password field page moves down as u see:
after typing, it scroll down
This library is always a bit janky. Try a configuration like this:
<KeyboardAwareScrollView
style={{ backgroundColor:
themeColors.boxPrimaryBackground, flexGrow: 1 }}
contentContainerStyle={{ width: '100%', margin: 0 }}
scrollEnabled={true}
extraScrollHeight={-125}
extraHeight={10}
keyboardOpeningTime={Number.MAX_SAFE_INTEGER}
showsVerticalScrollIndicator={false}
keyboardShouldPersistTaps={'handled'}
>
// add scroll content here
</ KeyboardAwareScrollView>
The thing you really need to add is the keyboardOpeningTime={Number.MAX_SAFE_INTEGER}. It has something to do with the animation inside the library. Good luck hope this helps.
I have seen your question on github as well, and its been a long time since that is in open state there.
I have the above problem resolved using KeyboardAvoidingView from react-native
import {KeyboardAvoidingView} from 'react-native'
I have replaced KeyboardAwareScrollView with KeyboardAvoidingView and this is working as needed.
Here is an app link that does this. You can download and see it's login page.

How to make an image of a <ImageBackground> tag darker (React Native)

I'm trying to create an image with a text on it, and in order for the the text to be clearly seen I need to make the image darker.
Also (don't sure if it matters or not) I need the background image to be touchable.
This question was asked several times here and I've seen some answers, but none of them worked for me, so I'm wondering if I'm missing something more crucial here.
My code is the following:
<View style={postStyles.container}>
<TouchableOpacity onPress={() =>
this.props.navigation.navigate('AnotherWindow')}>
<ImageBackground source={require('../../assets/images/my_img.jpg')}
style={{width: '100%', height: 150}}>
<Text style={postStyles.title} numberOfLines={2}>
My text
</Text>
</ImageBackground></TouchableOpacity>
From looking around here, I've tried the following solutions:
Tried to wrap the text element inside the imagebackground tag inside a
View element that has a style property of "backgroundColor" with value of 'rgba(255,0,0,0.5)' (also tried different values),
Tried to add this backgroundColor property to the styles of both the container itself, the TouchableOpacity element
Tried to above two solutions with the "elevation" property instead of backgroundColor (I work in Android).
None of the above solutions worked, in a sense that the background image didn't change at all, so I'm wondering if I'm missing something more crucial.
Thanks!
If anyone still having problems with the ImageBackground component, this is how i solved it, basically i set a view inside the image background which has the backgroundColor that darkens the image.
<ImageBackground
source={Images.background}
style={styles.imageBackground}
>
<View style={styles.innerContainer}>
{content}
</View>
</ImageBackground>
const styles = StyleSheet.create({
imageBackground: {
height: '100%',
width: '100%'
},
innerContainer: {
flex: 1,
backgroundColor: 'rgba(0,0,0, 0.60)'
},
});
if you want to make the image darker, you'll need the Image component and use the tintColor prop like:
<Image source={require('./your_image.png')} style={{ tintColor: 'cyan' }}>
this tintColor prop only works for Image component not ImageBackground, also if you want to add a text on the Image component, you'll need to positioning that text with position: 'absolute' or 'relative'
<View style={postStyles.container}>
<TouchableOpacity
onPress={() => his.props.navigation.navigate('AnotherWindow')}>}
>
<Image
source={require('./my_image.png')}
resizeMode="contain"
style={{ width: '100%', height: 150, tintColor: 'cyan' }}
/>
<Text style={postStyles.title} numberOfLines={2}>
My text
</Text>
</TouchableOpacity>
</View>
Also, if you implement this approach you'll need to calculate the dimensions of the screen for each device, well you'll need to check this other component from react-native: https://facebook.github.io/react-native/docs/dimensions
Please, let me know if this works :D
You should just add tintColor to ImageBackground imageStyle and you're done. easy peasy!
<TouchableOpacity onPress={() => this.props.navigation.navigate('AnotherWindow')}>
<ImageBackground source={require('../../assets/images/my_img.jpg')}
style={{width: '100%', height: 150}}
imageStyle={{tintColor: 'rgba(255,0,0,0.5)'}}>
<Text style={postStyles.title} numberOfLines={2}>
My text
</Text>
</ImageBackground>
</TouchableOpacity>

React-Native fixed Footer within ScrollView?

I would like to create Views with dynamic content that should have some kind of footer that should normally (if there is enough space) look like they are sticked to the bottom.
Before I introduced ScrollViews my code looked like this:
<View style={{flex: 1, justifyContent: 'space-between'}}>
<View>{content}</View>
<View>{stickyFooter}</View>
</View>
After introducing the ScrollView I had to remove flex: 1 because otherwise the ScrollView is not scrollable at all. After that justifyContent became useless because the height of the flex-container is not set to 100%. Therefore both Views just appear next to each other.
To make clear what my view should look like in general:
The button should not be sticked to the bottom, but it should appear at the bottom (if possible).
This is an old question now, but for the benefit of those who end up here from a google search like I did, I paste the solution that worked for me below.
Markup
render = () => {
return (
<View>
<ScrollView style={styles.container}>
...
</ScrollView>
<TouchableOpacity style={styles.floatingActionButton}>
<RkButton
rkType='stretch'>
<RkText>Do stuff</RkText>
</RkButton>
</TouchableOpacity>
</View>
)
}
Styles
const styles = StyleSheet.create(theme => ({
floatingActionButton: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
bottom: 10,
left: 10,
right: 10,
borderRadius: 10,
}
}));