How to space items in React or React Native - javascript

I am trying to space my components however I am having issues. I would like my grid to take up 90% of the screen and the gear icon to take 10%
<View
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
flex: 1,
flexDirection: 'row',
}}
onLayout={event => {
_handleWorkSpace(event);
}}>
<StatusBar hidden={true} />
<View style={{flex: 1}}>
<FlatGrid
itemDimension={96}
// maxDimension={128}
data={items}
style={styles.gridView}
// staticDimension={{width: 128, height: 128}}
fixed
spacing={10}
renderItem={({item}) => (
<View
onLayout={event => {
var {x, y, width, height} = event.nativeEvent.layout;
console.log(width, height);
}}
style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
<View style={{flex: 1}}>
<Icon name="settings" size={30} />
</View>
</View>
What I have
What I am hoping for
I was able to get the look but I had to change the grid flex value to 12. I know it's not the correct way so I am trying to figure how to do this

You put flex: 1 in both Views, this means that both will try to take up 50% of the space (1+1). If you want one to take 90% and the other one 10%, one will need flex: 9 and the other one flex: 1.
Just change the flex values:
<View style={{flex: 9}}>
<FlatGrid
...
/>
</View>
<View style={{flex: 1}}>
<Icon name="settings" size={30} />
</View>
To try to make it clearer: just imagine the sum of the flex values on the same level are 100%. Since you had 2 flex: 1, 1+1=2=100%, so 1=50%.
By making the change I suggested (flex: 9 and flex: 1) you can think of it like 9+1=10=100%, so 9=90% and 1=10%.

const {width} = Dimensions.get('window');
<View
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
flex: 1,
flexDirection: 'row',
}}
onLayout={event => {
_handleWorkSpace(event);
}}>
<StatusBar hidden={true} />
<View style={{width : 0.9*width}}>
<FlatGrid
itemDimension={96}
// maxDimension={128}
data={items}
style={styles.gridView}
// staticDimension={{width: 128, height: 128}}
fixed
spacing={10}
renderItem={({item}) => (
<View
onLayout={event => {
var {x, y, width, height} = event.nativeEvent.layout;
console.log(width, height);
}}
style={[styles.itemContainer, {backgroundColor: item.code}]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
<View style={{width : 0.1*width}}>
<Icon name="settings" size={30} />
</View>
</View>
try this, don't forget to import Dimensions from react-native
use cosnt {width} = Dimensions.... out of return statement.

You can set your gear icon as an absolute element:
<View style={styles.grid}>
<Octicons name="gear" size={iconSize} color="black" style={styles.icon} />
<FlatGrid
itemDimension={130}
data={items}
style={styles.gridView}
spacing={10}
renderItem={({ item }) => (
<View style={[styles.itemContainer, { backgroundColor: item.code }]}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemCode}>{item.code}</Text>
</View>
)}
/>
</View>
with the following styles:
grid: {
alignSelf: 'center',
width: width * 0.9,
},
icon: {
position: 'absolute',
right: -iconSize,
top: 0,
}
Here is a working snack: https://snack.expo.dev/#hristoeftimov/absolute-icon

Related

React native Flatlist doesn't scroll

I have an weather app in react native that uses react-native-app-intro-slider that is basically a vertical FlatList. This is my App render
return (
<AppIntroSlider style = {{backgroundColor:'#4c669f'}}
renderItem = {_renderItem}
data = {dataToRender}
showDoneButton = {false}
showPrevButton = {false}
showNextButton = {false}/>
)
And the Slider items that i'm rendering look like this
_renderItem = ( {item} ) => {
return (
<View style={{flex:1}}>
<Text style={{fontSize:20, marginTop:20, color:'white',fontSize:25, alignSelf:'center'}}>{item.name}</Text>
<View style={{ flexDirection:'row', marginTop:15, alignItems:'center', justifyContent:'center'}}>
<Image source={{uri: 'http://openweathermap.org/img/wn/' + item.icon + '#2x.png'}} style={{width:90, height:90}}/>
<Text style={{color:'white', fontSize:60}}>{`${_.round(item.temp)}°C`}</Text>
</View>
<View>
<Text style={{alignSelf:'center', justifyContent:'center', color:'white', fontSize:20}}>{item.clouds}</Text>
<View style={{display:'flex', alignItems:'flex-start', marginLeft:40 }}>
<View style={{ marginTop:40, flexDirection:'row'}}>
<Icon name='wind' size={28}/>
<Text style={{marginLeft:5, fontSize:22, color:'white'}}>{item.wind} km/h</Text>
</View>
<View style={{ marginTop:10, flexDirection:'row'}}>
<Icon name='temperature-low' size={28} />
<Text style={{marginLeft:5, fontSize:22, color:'white'}}>{_.round(item.temp_min,1)} °C</Text>
</View>
<View style={{ marginTop:10, flexDirection:'row' }}>
<Icon name='temperature-high' size={28} />
<Text style={{marginLeft:5, fontSize:22, color:'white'}}>{_.round(item.temp_max,1)} °C</Text>
</View>
<View style={{ marginTop:10, flexDirection:'row' }}>
<Icon name='compress-alt' size={28} />
<Text style={{marginLeft:5, fontSize:22, color:'white'}}>{item.air_pressure} hPa</Text>
</View>
</View>
</View>
<View>
<FlatList
data={dataToRender16}
renderItem={renderFlatListItem}/>
</View>
</View>
);
}
And the issue is that the FlatList in the rendered item (in the second code snippet) is not scrolling down, I've tried changing some styles but none of that worked
First of your dataToRender16 must have some unique id ,and you must add keyExtractor to your FlatList.
checkout the following example:
<FlatList
keyExtractor={(item, index) => item.id}
data={dataItems}
renderItem={itemData => (
<ItemComponent
id={itemData.item.id}
onDelete={removeItemHandler}
title={itemData.item.value}
/>
)}
/>
Adding flex:1 to styles of the that FlatList is netsted is solved the issue
<View style={{flex:1, alignItems:'center', paddingTop:50}}>
<FlatList
data={dataToRender16 }
renderItem={renderFlatListItem}/>
</View>

How to make my Bottom Bar fixed in React Native?

Hey
I have my bottom bar out the Scroll View component,But it still scroll with the other components.
How can i make it fixed ?
"
<SafeAreaView styles={SafeViewAndroid.AndroidSafeArea}>
<View style={{ backgroundColor: "#fff", padding: 15 }}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar cityHandler={setCity} />
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<Categories />
<RestaurantItems restaurantData={restaurantData} />
</ScrollView>
<Divider width={1} />
<BottomTabs />
</SafeAreaView>
"
Entire Code Screen
You can use flex proportions to separate the and components, as below
<SafeAreaView styles={SafeViewAndroid.AndroidSafeArea}>
<View style={{ backgroundColor: "#fff", padding: 15, flex : 1 }}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar cityHandler={setCity} />
</View>
<View style= {{flex : 3 }}>
<ScrollView showsVerticalScrollIndicator={false}>
<Categories />
<RestaurantItems restaurantData={restaurantData} />
</ScrollView>
</View>
<View style= {{flex : 1 }}>
<Divider width={1} />
<BottomTabs />
</View>
</SafeAreaView>
You can do it by styling your button component as -
<TouchableOpacity
style={{
width: 60,
height: 60,
backgroundColor: 'red',
position: 'absolute',
bottom: 50,
justifyContent: 'center',
alignItems: 'center',
}}
onPress={() => {
console.log('Button Pressed')
}}
>
<Text>Hello Bottom Button</Text>
</TouchableOpacity>

"undefined is not an object", need to check if allNotes array is empty. How?

Feel like this is kind of a silly question but I need to only return the allNotes map data if allNotes isn't empty (its an array). This seems like just a simple if/else but really can't figure out how to do this in this context (inside view). Right now, I get the error in the title when nothing is in the array. when it has data everything is fine.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes.map((item) => {
return (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
})}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}
Again I Know this is something really simple but I can't get the formatting correct. Don't know what the correct method of doing this would be. Thanks!
Could always double check that allNotes is defined like this although it may be better to default allNotes to an empty array and then confirm here that it's what you'd expect.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes && allNotes.map(item => (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
)}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}

How to display Icon in middle of screen in react native

Here, I am displaying "icon="check-decagram" type="MaterialCommunityIcons" in center, but its just coming in center and 20 padding from top. I have to display it middle of the mobile screen. I tried may be I am doing some wrong .Please correct me .
return(
<ImageBackground source={BG} style={styles.imgBG}>
<ScrollView>
<View>
<Header title={title} icon={icon} navigation={navigation} />
</View>
<View style={{ flexDirection: 'column', backgroundColor: '#ffff',}}>
<View style={{
flexDirection:'column', backgroundColor:'#fff',alignItems:'center',paddingTop:20,justifyContent: 'center'}}>
<IconXL icon="check-decagram" type="MaterialCommunityIcons" style={{ color: 'green' }}/>
</View>
<View style={{
flexDirection:'row', backgroundColor:'#ffff',padding:20,flexWrap:'wrap'}}>
<SmallText textColor="grey" text={`v${updateResponse.updateStatusList.currentAppVersion} `}/>
<SmallText textColor="grey" text={`${updateResponse.updateStatusList.desc}`}/>
</View>
</View>
</ScrollView>
</ImageBackground>
)}
// Thanks
try to add two more property height: '100%' and width: '100%' in superview of icon,
like,
<View style={{flexDirection:'column',height: '100%',width: '100%',backgroundColor:'#fff',alignItems:'center',paddingTop:2,justifyContent: 'center'}}>
<IconXL icon="check-decagram" type="MaterialCommunityIcons" style={{ color:'green' }}/>
</View>
Hope this works for you,
Good luck.
You can try something like.
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
}}>
<Text style={{backgroundColor: 'red'}}>
Your Text
</Text>

How to use justify content property in react native?

I'm trying to align contents to the left of image.But here what I'm getting is the text will take the left out space after the image.I'm expecting the float-align:left property just as in css to be here.So that I've used alignItems:flex-end.But not getting the output.Is there any possibility of doing this.What I've tried is as below
updated
<ScrollView>
{article.map(a =>
<TouchableOpacity onPress={() =>this.props.navigation.navigate('Article')}>
<CardSection>
<View style={{ flexDirection: 'row'}}>
<Image source={{uri:a.poster}} style={styles.thumbnail_style}/>
<Text style={styles.textStyle}>
{a.title}</Text>
</View>
</CardSection>
</TouchableOpacity>
)}
</ScrollView>
);
}
}
const styles= StyleSheet.create({
thumbnail_style :{
height: 50,
width:50,
},
textStyle:{
paddingTop:20,
fontSize:16,
paddingLeft:10,
marginRight:20
}
});
What I'm getting is as below
Could you explain why you are setting the Image inside your Text?
If you want the image on top of the text simply do:
<Image />
<Text></Text>
otherwise, if you want them placed from left to right you can wrap them in a view and use flexDirection
<View style = {{flexDirection: 'row'}}>
<Text></Text>
<Image />
</View>
<View style = {{flexDirection: 'row'}}>
<Image
style={{height: 100, width: 100}}
source = {{ uri: `https://x1.xingassets.com/assets/frontend_minified/img/users/nobody_m.original.jpg` }}/>
<Text style = {{padding:10, flex: 1, flexWrap: 'wrap'}}>my text</Text>
</View>
I am not sure why you are wrapping Image inside Text. Since you want Image and Text to appear side by side you need it to be siblings. You can have like:
<View>
<Image />
<Text />
</View>
Then you can apply following style to View
{
flexDirection: 'row',
alignItems: 'flex-start'
}

Categories