React-Native Align Issue - css

I just want the Icon to be on the left and the text to be on center.
I have this structure:
<View style={styles.mainContainer}>
<Error screen={screen}/>
<View style={styles.headerContainer}>
{back &&
<Icon
raised
name='arrow-back'
onPress={ onBackPress }
containerStyle={styles.back}/>
}
<Text style={styles.header}>{ title }</Text>
</View>
<View style={styles.contentContainer}>
{ children }
</View>
</View>
Kinda like this:
-> MainContainer
--> HeaderContainer
----> Back button
----> Title
mainContainer: {
flex: 1,
flexDirection: 'column',
alignItems: 'stretch',
justifyContent: 'flex-start'
},
headerContainer: {
flex: 1,
padding: 10,
flexDirection: 'row',
// ommited for clarity
},
back: {
alignSelf: 'flex-start'
},
header: {
fontSize: 24,
alignSelf: 'center'
},
But it doesnt work as it produces:
I also tried adding in HeaderContainer:
justifyContent: 'space-between',
and a blank <View />, but the result is not good:
As you can see, it's not centered really.
Edit Produces:
It's not really centered, because we put an imaginary thrid element. Can we do it with only two elemets? One in start and other on center?
Why is it not posible?

Try the following:
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}>
<View style={{ flex: 1 }}>
{leftContent}
</View>
<View style={{ flex: 1, alignItems: 'center' }}>
{centerContent}
</View>
<View style={{ flex: 1, alignItems: 'flex-end' }}>
{rightContent}
</View>
</View>
Don't forget to set textAlign: 'center' if center component is <Text> or textAlign: 'right' if the right component is Text.

Put your Icon and text in separate Views and asign a flex to it something like this
<View style={styles.mainContainer}>
<Error screen={screen}/>
<View style={styles.headerContainer}>
<View style={{flex:.3,alignSelf:'flex-start}}>
{back &&
<Icon
raised
name='arrow-back'
onPress={ onBackPress }
containerStyle={styles.back}/>
}
</View>
<View style={{flex:.7,alignSelf:'flex-end',alignItems:'center'}}>
<Text style={styles.header}>{ title }</Text>
</View>
</View>
<View style={styles.contentContainer}>
{ children }
</View>
</View>
I think it shoud fix the problem

Related

How to make a textInput stretch an entire space dynamically without setting width - react native

I have a react native project. I currently have a bar that I made which has a text input and view selector. The view selector is small and the text nput is currently small. I dont want anything to change but I want the textInput to fill the empty white space between the input and the view selector dynamically.
here is the my code:
import React, { useState } from 'react'
import { Text, View, StyleSheet, TextInput } from 'react-native'
import { Feather } from '#expo/vector-icons'
const SearchAndFilterComponent = () => {
const [search, setSearch] = useState()
return (
<View style={styles.container}>
<View style={styles.bar}>
<View style={styles.searchContainer}>
<View style={styles.search}>
----------------------------------------------------------------------------------
<View style={styles.searchIconContainer}>
<Feather style={styles.searchIcon} name='search' color={'#273be2'} size={24} />
</View>
<View style={styles.searchInputContainer}>
<TextInput style={styles.searchInput} value={search} onChange={setSearch} placeholder={'search'}/>
</View>
----------------------------------------------------------------------------------
</View>
<View style={styles.navigationContainer}>
<Feather name='navigation' color={'#273be2'} size={24} />
</View>
</View>
<View style={styles.mapContainer}>
<View style={styles.splitter}></View>
<Feather style={styles.buttonIcon} name='map' color={'#273be2'} size={24} />
<Text style={styles.text}>Map</Text>
</View>
</View>
<View style={styles.bar}>
<View style={styles.sorfAndFilter}>
<View style={styles.buttonContainer}>
<Feather name='filter' color={'#273be2'} size={24} />
<Text style={styles.text}>Filter</Text>
</View>
<View style={styles.buttonContainer}>
<Feather name='sliders' color={'#273be2'} size={24} />
<Text style={styles.text}>Sort</Text>
</View>
</View>
<View style={styles.buttonContainer}>
<Feather name='download' color={'#273be2'} size={24} />
<Text style={styles.text}>Save</Text>
</View>
</View>
<View style={styles.bar}>
<View>
<Text style={styles.text}>Results: "Palm Springs, CA"</Text>
</View>
<View>
<Text style={styles.text}>2,345 Properties</Text>
</View>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
width: '100%',
marginTop: 50
},
bar: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between'
},
searchContainer: {
display: 'flex',
flexDirection: 'row'
},
search: {
display: 'flex',
flexDirection: 'row'
},
splitter: {
height: 20,
width: 2,
backgroundColor: 'lightgrey',
marginHorizontal: 8
},
mapContainer: {
display: 'flex',
flexDirection: 'row'
},
sorfAndFilter: {
display: 'flex',
flexDirection: 'row'
},
buttonContainer: {
display: 'flex',
flexDirection: 'row'
},
searchInputContainer: {
display: 'flex',
flexDirection: 'column',
alignItems: 'stretch'
},
searchInput: {
fontSize: 17,
borderBottomWidth: 2,
borderBottomColor: 'grey',
alignItems: 'stretch'
},
text: {
fontSize: 17
},
buttonIcon: {
marginRight: 4
}
})
export default SearchAndFilterComponent
Here is an image:
Use flexbox.
Here is an example with tailwind css.
<View
style={[
tw`flex flex-row items-center mx-1 mb-1 rounded-full`,
{ backgroundColor: "#2E2E2E" },
]}
>
<TextInput
style={[
tw`m-0 p-0 px-4 py-3 flex-grow text-white text-lg`,
{},
]}
placeholder="Type message here ..."
placeholderTextColor="#777"
/>
<Icon
name="send"
type="material"
size={20}
color="white"
style={[
tw`rounded-full p-3 mr-1`,
{ backgroundColor: "#B50055", opacity: 1 },
]}
/>
</View>
The idea is to use flexbox on the View and flex-grow on the TextInput.
The rest of the stuff will take the least space.

React Native: Button at the right end of of Text

React Native learner here.
I am trying to show the suggestions as below:
<TouchableOpacity
style={{
backgroundColor: 'transparent',
flexDirection: 'row',
flexWrap: 'wrap',
}}
onPress={() => {
setSelectedValue(item);
setFilteredFilms([]);
}}>
<View>
<Text style={styles.itemText}>{item.title}</Text>
<Button
title={'Click'}
style={{
backgroundColor: 'green',
right: 0,
paddingRight: 0,
marginRight: 0,
}}></Button>
</View>
</TouchableOpacity>
...
itemText: {
fontSize: 15,
paddingTop: 5,
paddingBottom: 5,
margin: 2,
alignItems: 'flex-start',
},
infoText: {
textAlign: 'center',
fontSize: 16,
},
Output looks like below:
I want my suggestion's Text in the left side, while Click button always at the right side fixed with fixed length.
Text and Button region shouldn't overlap each other.
Any help or guidance about how to do it. Highly appreciated !!
P.S.: With style={{flexDirection: 'row'}} in <View> my Buttons in Suggestion box get pushed to right side and not visible as below:
I expect something like this:
You have to use flexDirection:'row' for inner View which contain the Text and the Button
<TouchableOpacity
style={{
backgroundColor: 'transparent',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
}}
onPress={() => {}}>
<Text style={{ maxWidth: '90%' }}>
{item.title}
</Text>
<View>
<Text style={{ backgroundColor: 'blue', alignItems: 'center' }}>
Click
</Text>
</View>
</TouchableOpacity>
Don't forget to look at : https://www.npmjs.com/package/react-native-read-more-text
this will help you get through it.

View to fit the screen in React Native

Hello there guys
i have a problem with CSS in react native, i want to fit all my components in the screen without ScrollView but i cant seem to figure out what is my problem(i tried to change values for margins or paddings but it will look different in every device.)
As you can see at the attached image:
As you can see the graph below is not in the screen, i need to scroll view to the graph(which i dont want)
here is the code + css : (I dropped some lines to shorten the code(Like the carousel components and etc)
<View style={{ backgroundColor: "#fff" , flex: 1 }}>
<LinearGradient
colors={["#4c669f", "#3b5998", "#192f6a"]}
start={[0, 0]}
end={[1, 0]}
>
<View style={{ marginHorizontal: 20, paddingVertical: 48 }}>
<View style={styles.imageContainer}>
<View>
<View style={styles.check}>
<Ionicons name="md-checkmark" size={20} color={colors.pink} />
</View>
<Image
source={require("../assets/profile-pic.jpeg")}
style={{
width: 100,
height: 100,
borderRadius: 32,
}}
/>
</View>
</View>
<View style={[styles.center, { marginVertical: 12 }]}>
<Text style={styles.title}>
{currentUser.name + " " + currentUser.lastName}
</Text>
<Text style={[styles.subTitle, { marginTop: 8 }]}>
{businessDetails.bussinesName}
</Text>
</View>
</View>
</LinearGradient>
<View style={styles.container}>
<View style={styles.statContainer}>
<Text style={styles.statNumber}>1,700₪</Text>
<Text style={styles.stat}>הכנסה חודשית תופיע כאן</Text>
</View>
</View>
<View style={styles.center}>
<Text style={styles.textGraphTitle}>Graphs Analysis:</Text>
</View>
<View>
</View>
</View>
);
CSS:
center: {
alignItems: "center",
justifyContent: "center",
},
imageContainer: {
alignItems: "center",
justifyContent: "center",
marginTop: 1,
shadowColor: colors.darkBg,
shadowOffset: { height: 3, width: 1 },
shadowOpacity: 0.5,
},
container: {
paddingVertical: 24,
paddingHorizontal: 32,
marginBottom: 8,
backgroundColor: colors.lightBg,
flexDirection: "row",
justifyContent: "space-between",
marginHorizontal: 16,
borderRadius: 16,
marginTop: -48,
},
statContainer: {
alignItems: "center",
justifyContent: "center",
flex: 1,
},
You are asking responsive app design. Basically, you can use for width and height percentages or dimension.
import { Dimensions} from 'react-native'
const {width, height} = Dimensions.get('window')
One more approach is to use react-native-screens library

how can I reduce space between these View components React Native

So I am just learning.... building a quiz app in react-native and I think the space between the first row of the buttons and the second row of the buttons is too much, how can I reduce it?
thanks
<LinearGradient colors={['#0D0B18','#28263E']} style={styles.container}>
<Text style={styles.question}>After Jesus rose from the dead, how long did he remain on earth before ascending to heaven? </Text>
<View style={styles.buttonRow}>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>12 days</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>40 days</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity style={styles.buttonStyle}onPress={this.onPress}>
<Text style={styles.buttonText}>3 months</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>1 year</Text>
</TouchableOpacity>
</View>
<View style={styles.progressStyle}>
<ProgressViewIOS
style={styles.progressView}
progress={(0.2)}
/>
</View>
</LinearGradient>
const styles = StyleSheet.create ({
container: {
flex: 3,
},
question: {
paddingTop: '20%',
padding: 30,
flex: 1,
color: '#fff',
fontSize: 25
},
buttonRow : {
marginTop: 0,
flexDirection: 'row',
color: '#fff',
alignItems: 'center',
justifyContent: 'space-evenly',
},
buttonStyle: {
backgroundColor: '#fff',
width: '40%',
height: '50%',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10
},
buttonText: {
color: '#000'
},
progressView: {
width: '90%',
},
progressStyle: {
padding: 20,
alignItems: 'center',
justifyContent: 'center',
}
});
Small, you don't need flex: 3 for an element with no siblings, it shouldn't really matter but you only need to assign it flex: 1 if it is alone and should not take up more space relative to it's siblings.
To get your buttons to display nicely you should give them a wrapper:
<View style={styles.buttonWrapper}>
<View style={styles.buttonRow}>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>12 days</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>40 days</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>3 months</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.buttonStyle} onPress={this.onPress}>
<Text style={styles.buttonText}>1 year</Text>
</TouchableOpacity>
</View>
</View>
where styles.buttonWrapper is just:
buttonWrapper: {
flex: 1,
justifyContent: "space-around"
},
Now your button group and question will occupy an even amount of space after the height of your progress bar is taken into account and the button group will be squished together thanks to justifyContent: 'space-around'
This alters the size of the buttons however, so for this to work you should change the button styles to something like:
buttonStyle: {
backgroundColor: "#fff",
flex: 1,
marginHorizontal: 5,
aspectRatio: 2,
justifyContent: "center",
alignItems: "center",
borderRadius: 10
},
You can see this in action here: https://snack.expo.io/HkWF-EsA7
Flex can be a little weird when you're just starting out, so I recommend experimenting a lot. There are interesting properties like aspectRatio, alignContent, alignSelf and many others (learn more about those here). It may be frustrating at first but your layouts will be much better if you can avoid using width and height and entirely use flex instead. This isn't always possible but I think it will work just fine for what you're trying to accomplish.
I hope this gave you some idea of what you could do moving forward, if you have any questions let me know!

How can I mix fixed and dynamic size elements in a flexbox container?

I'm trying to create a layout that utilizes flexbox' automatic sizing but also contains fixed-size items:
<View style={{ height: 70, alignItems: "center" }}>
<Text style={{ flex: 1, textAlign: "right", paddingRight: 10 }}>left text</Text>
<Image style={{ width: 70, height: 70 }} src={require('./img.png')} />
<Text style={{ flex: 1, textAlign: "left", paddingLeft: 10 }}>right text</Text>
</View>
I want the image to be centered in the UI and have the text views equally take the remaining width. The actual result is that one of the text views is larger than the other as if the rendering doesn't take the width of the image view into account.
Finally found the correct way of doing this. To have fixed size items in a flex layout one shouldn't use width/height but flex: 0 and flexBasis. This approach initially didn't work for me because a component wrapping my component wasn't sized correctly and messed with the flex rendering. flexBasis seems to be density-independent pixels when it is set to an absolute number.
Proof of concept on expo.io
import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View>
<Text>Test</Text>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
<Text>Test</Text>
<View style={styles.container}>
<Text style={styles.text1}>{"Left\nText"}</Text>
<View style={styles.view} />
<Text style={styles.text2}>Test</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
view: {
flex: 0,
flexBasis: 50,
height: 50,
backgroundColor: "red",
},
text1: {
flex: 1,
textAlign: "right",
paddingRight: 10,
},
text2: {
flex: 1,
textAlign: "left",
paddingLeft: 10,
}
});

Resources