Creating table layout in React Native app - react-native

I'm trying to create a table layout in my React Native app and I think I'm pretty close but rows seem to spread out over the whole screen. I'd like the table and all its rows to stay at the top of the screen. I tried flex-start but didn't seem to help. Also, notice that I really would like the white background to show in between columns. In my code, all the columns merge into one.
Here's the outcome I'm trying to achieve:
And here's a link to my snack where you can see and play with the code and here's the code as it is now -- see below:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.tableContainer}>
<View style={styles.tableRow}>
<View style={styles.tableColumnHeader}>
<Text style={styles.textHeader}>Monday, February 6, 2021!</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>10:00 AM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>12:00 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>2 Hrs</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={{...styles.textLineItem, justifyContent: "flex-end"}}>$25.00</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>1:00 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>5:30 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>4.5 Hrs</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={{...styles.textLineItem, justifyContent: "flex-end"}}>$56.25</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnHeader}>
<Text style={styles.textHeader}>Tuesday, February 7, 2021!</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>9:00 AM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>12:00 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>3 Hrs</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={{...styles.textLineItem, justifyContent: "flex-end"}}>$37.50</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>1:00 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>5:30 PM</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={styles.textLineItem}>4.5 Hrs</Text>
</View>
<View style={styles.tableColumnRegular}>
<Text style={{...styles.textLineItem, justifyContent: "flex-end"}}>$56.25</Text>
</View>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingTop: Constants.statusBarHeight,
backgroundColor: "#ecf0f1",
padding: 8,
},
tableContainer: {
flex: 1,
},
tableRow: {
flex: 1,
flexDirection: "row",
backgroundColor: "white"
},
tableColumnRegular: {
flex: 1,
flexDirection: "column",
backgroundColor: "#c7c7c7",
alignItems: "center",
height: 25,
padding: 2
},
tableColumnHeader: {
flex: 4,
flexDirection: "row",
backgroundColor: "tomato",
height: 25,
alignItems: "center",
justifyContent: "center"
},
textHeader: {
color: "white"
},
textLineItem: {
color: "black"
}
});
I'd appreciate some help with this.

I figured it out. I hope this solution helps others too. Obviously, I changed the colors from the original specs but that would be easy to update if someone else were to use this code.
Here's the link to my snack.
And here's the code:
export default function App() {
return (
<View style={styles.container}>
<View style={styles.tableContainer}>
<View style={styles.tableRowHeader}>
<View style={styles.tableColumnHeader}>
<Text style={styles.textHeader}>Monday, February 8, 2021</Text>
<Text style={styles.textHeaderSubTitle}>(6.5 Hrs)</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnClockInOutTimes}>
<Text style={styles.textLineItem}>10:00 AM - 12:00 PM</Text>
</View>
<View style={styles.tableColumnTotals}>
<Text style={styles.textLineItem}>2 Hrs</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnClockInOutTimes}>
<Text style={styles.textLineItem}>1:00 PM - 5:30 PM</Text>
</View>
<View style={styles.tableColumnTotals}>
<Text style={styles.textLineItem}>4.5 Hrs</Text>
</View>
</View>
<View style={styles.tableRowHeader}>
<View style={styles.tableColumnHeader}>
<Text style={styles.textHeader}>Tuesday, February 9, 2021</Text>
<Text style={styles.textHeaderSubTitle}>(8 Hrs)</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnClockInOutTimes}>
<Text style={styles.textLineItem}>8:30 AM - 12:00 PM</Text>
</View>
<View style={styles.tableColumnTotals}>
<Text style={styles.textLineItem}>3.5 Hrs</Text>
</View>
</View>
<View style={styles.tableRow}>
<View style={styles.tableColumnClockInOutTimes}>
<Text style={styles.textLineItem}>1:00 PM - 5:30 PM</Text>
</View>
<View style={styles.tableColumnTotals}>
<Text style={styles.textLineItem}>4.5 Hrs</Text>
</View>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#000000",
flex: 1,
padding: 10
},
tableColumnHeader: {
alignItems: "center",
backgroundColor: "#1FE0A2",
flex: 5,
justifyContent: "center"
},
tableColumnClockInOutTimes: {
alignItems: "center",
backgroundColor: "#000000",
flex: 3,
justifyContent: "center",
margin: 1
},
tableColumnTotals: {
alignItems: "center",
backgroundColor: "#000000",
flex: 2,
justifyContent: "center",
margin: 1
},
tableRow: {
flex: 5,
flexDirection: "row",
maxHeight: 30
},
tableRowHeader: {
flex: 5,
flexDirection: "row",
maxHeight: 40
},
tableContainer: {
backgroundColor: "#202020",
borderRadius: 5,
flex: 1,
marginTop: 0,
padding: 10
},
textHeader: {
color: "#000000",
fontWeight: "bold"
},
textHeaderSubTitle: {
color: "#000000",
fontSize: 12
},
textLineItem: {
color: "#FFFFFF"
}
});

Related

How to design a rank with flexbox and page controllview

I'm trying to put the name's on the left and the rank on the right. I tryed the flexDirection row with a space between or space evenly but it still doesn't work.
Do you have any solution for that ?
Also my function :
renderRanking = () => {
return this.state.ranking.map((element) => {
return (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-’‘’',
}}>
<View style={{flex: 1}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
</View>
);
});
};
And my render
render() {
return (
<SafeAreaView style={{flex: 1, backgroundColor: 'black'}}>
<View style={{flex: 1, backgroundColor: 'black'}}>
<ScrollView>
<View
style={{
flex: 1,
}}>
<Text>{this.OpenDecibels()}</Text>
</View>
<View style={{paddingBottom: 30}}>
<PageControlView defaultPage={1}>
<View>{this.renderRanking()}</View>
</PageControlView>
</View>
</ScrollView>
</View>
</SafeAreaView>
);
}
}
Try this way
<View
style={{
flexDirection: 'row',
justifyContent: 'space-’‘’',
}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
You should try below snippet in your renderRanking function.
renderRanking = () => {
return this.state.ranking.map((element) => {
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{fontSize: 20, color: 'white'}}>{element.club}</Text>
<Text style={{fontSize: 20, color: 'white'}}>
{element.moyenne}
</Text>
</View>
);
});
};
Also change
<PageControlView defaultPage={1}>
<View>{this.renderRanking()}</View>
</PageControlView>
To
<PageControlView defaultPage={1}>{this.renderRanking()}</PageControlView>

ImageBackground not showing image on some devices

I am trying to use a CustomCallout with a ImageBackground in it. I notice a really strange behavior when testing the application on two different devices (both Android). The image is showed correctly on the older device with lower display, but on the new device (p30 lite) the image is not appearing.. any ideas? here is my code:
class CustomCallout extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.calloutStyle}>
<View>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<ImageBackground
source={{ uri: this.props.image }}
style={styles.bgImage}
>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</ImageBackground>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
CustomCallout.propTypes = propTypes;
const styles = StyleSheet.create({
calloutStyle: {
height: 200,
width: 280,
backgroundColor: '#61adc8',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
padding: 12,
borderRadius: 20,
shadowColor: 'black',
overflow: 'hidden'
},
bgImage: {
width: '100%',
height: '100%',
justifyContent: 'flex-end',
},
placeRow: {
flexDirection: 'row'
},
placeHeader: {
height: '80%'
},
placeDetail: {
justifyContent: 'space-between',
height: '10%'
},
placeRating: {
height: '10%',
justifyContent:'flex-start',
},
titleContainer: {
backgroundColor: 'rgba(0,0,0,0.5)',
shadowOffset: { width: 0, height: 2},
shadowRadius: 6,
shadowOpacity: 0.26,
elevation: 55,
borderRadius: 10,
alignItems: 'center'
},
title: {
color: 'white',
fontSize: 20
}
});
export default CustomCallout;
We cant put ImageBackground wherever we want.. I don't know the exact theory. But Just put the ImageBackgroung tag outside the view and try to even put on different views too.. If anyone know plz correct me. Here is a working example.
Put ImageBackground to entire component
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Or you can put to only both components
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</ImageBackground>
</View>
</View>
);
}
}
or put ImageBackground to inside view only
render() {
return (
<View style={styles.calloutStyle}>
<View>
<ImageBackground
source={{ uri: 'https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg' }}
style={styles.bgImage}
>
<View style={{ ...styles.placeRow, ...styles.placeHeader }}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>
{this.props.placeName}
</Text>
</View>
</View>
</ImageBackground>
<View style={{ ...styles.placeRow, ...styles.placeDetail }}>
<Text>{this.props.distance}m</Text>
<Text>{this.getPlaceType(this.props.placeType)}</Text>
</View>
<View style={{ ...styles.placeRow, ...styles.placeRating }}>
<StarRating
disabled={false}
emptyStar={'ios-star-outline'}
fullStar={'ios-star'}
halfStar={'ios-star-half'}
iconSet={'Ionicons'}
maxStars={7}
rating={4}
fullStarColor={'#FDCC0D'}
starSize={20}
/>
</View>
</View>
</View>
);
}
}
Try this out and let me know the result.. :)

Place a component to middle right in React Native

I am still learning about react native especially flexbox. So I have a TouchableOpacity that have some child components on it, like this:
And the problem is I can't move that arrow icon to the middle right of TouchableOpacity. I try with
justifyContent: 'center', alignItems: 'flex-end' But nothing happened. Here is my code :
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={
[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]
}
>
{item.status}
</Text>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>
And this is the style:
const styles = {
channelStyle: {
fontSize: 25,
paddingLeft: 30
},
onlineTextStyle: {
paddingLeft: 30,
color: 'green'
},
offlineTextStyle: {
paddingLeft: 30,
color: 'red'
},
footerTextStyle: {
flex: 1,
textAlign: 'center',
color: '#fff',
padding: 5,
fontSize: 18
},
arrowIconStyle: {
justifyContent: 'center',
alignItems: 'flex-end'
}
};
Is there something I missed?
Could you try the following and let me know how it goes?
// 1. Add flexDirection row here.
<CardSection style={{ flex: 1, flexDirection: 'row' }}>
...code...
// 2. Add alignSelf here.
<Icons name="arrow-right" size={50} style={[styles.arrowIconStyle, {alignSelf: 'flex-end'}]} />
</CardSection>
If that doesn't work, try not doing the previous step 2 and instead try this.
...code...
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
const styles = {
...code...
arrowIconStyle: {
justifyContent: 'center',
alignSelf: 'flex-end'
}
};
Update
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]}>
{item.status}
</Text>
</View>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>

How to set arrow icon center to the screen end in list item in react native

I am new to react native, In my application I have list. So that i have taken flatlist. I have designed the list item. But arrow icon need to set end of the item. I have tried many ways how to do this.
This is the my code
<View style={styles.MainContainer}>
<FlatList
data={ this.state.FlatListItems }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={
({item}) =>
<View style={styles.main}>
<View style={styles.itemContainer}>
<View>
<Image source={require('./resource/ic_drawer.png')} />
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)} >
{item.key}
</Text>
</View>
<View style={styles.balanceItem}>
<View>
<Text >Balance</Text>
<Text >$89.04</Text>
</View>
<View style={styles.subItem}>
<View>
<Text >Account number</Text>
<Text >743509-001</Text>
</View>
<View style={styles.balanceItem}>
<Text >Meter number</Text>
<Text >17976849</Text>
</View>
</View>
</View>
<View style={styles.balanceItem}>
<View style={styles.duenbuttonItem}>
<View>
<Text >Due Date</Text>
<Text >30/09/2016</Text>
</View>
</View>
<TouchableOpacity style={styles.btn} onPress={this.login}><Text style={{color: 'white'}}>PAY NOW</Text></TouchableOpacity>
</View>
</View>
<Image source={require('./resource/arrow_24.png')} style={styles.arrowImage}/>
</View>
}
/>
</View>
and this is my styles
const styles = StyleSheet.create({
MainContainer :{
// Setting up View inside content in Vertically center.
justifyContent: 'center',
flex:1,
margin: 10
},
item: {
padding: 0,
fontSize: 18,
},
itemContainer :{
flex: 1,
flexDirection: 'row',
padding : 10,
},
subItem: {
marginTop: 10,
flexDirection: 'row',
},
btn:{
borderRadius: 10,
alignSelf: 'stretch',
backgroundColor: '#003366',
padding: 10,
marginTop: 10,
alignItems: 'center',
},
balanceItem: {
marginLeft: 5,
},
duenbuttonItem: {
marginLeft: 10,
flexDirection: 'row',
},
arrowImage: {
justifyContent: 'flex-end',
justifyContent: 'center',
},
main:{
flex: 1,
}
});
And this the output of the above code
Here my requirement is the arrow image end of the item in center. So please guide me how to do this?

Layout arrangement in React Native

I'm trying to work on this Instagram layout using React Native:
However, I'm unable to arrange the layout properly. Here is my code:
import React from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import StatusBarBackground from './StatusBarBackground';
export default class App extends React.Component {
render() {
return (
<View>
<StatusBarBackground />
<View style={styles.user_profile}>
<View style={styles.container}>
<Image style={styles.image} source={require('./images/user_profile.jpg')}/>
</View>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.container}>
<Text style={styles.numbers}>128</Text>
<Text style={styles.grey_text}>posts</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>256</Text>
<Text style={styles.grey_text}>followers</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>184</Text>
<Text style={styles.grey_text}>following</Text>
</View>
</View>
<View style={styles.btnContainer}>
<Button title="Edit Profile" color="#000" backgroundColor="#CCC" raised={true} onPress={this.onPressEditProfile} />
</View>
</View>
</View>
);
}
onPressEditProfile(event) {
console.log('Clicked Edit Profile');
}
}
const styles = StyleSheet.create({
user_profile: {
width: '100%',
height: 120,
alignItems: 'flex-start',
flexDirection: 'row',
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
image: {
height: 100,
borderRadius: 50,
width: 100,
margin: 10,
alignItems: 'center',
justifyContent: 'center',
},
grey_text: {
color: '#999',
},
numbers: {
fontWeight: 'bold',
},
btnContainer: {
backgroundColor: '#CCC',
borderRadius: 10,
padding: 10,
},
});
It looks like this now:
What did I miss in the layout?
You just applied flexDirection: 'row' to common container so it was cause of your result layout.
I've provided some pseudocode just for your understanding.
const style = StyleSheet.create({
container: {},
infoTopRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
infoBottomRow: {
justifyContent: 'center',
alignItems: 'center',
},
});
<View style={...}>
<Avatar/>
<View style={...}> {/* <---- here should be flexDirection: 'column' or just don't set any value for it */}
<View style={style.infoTopRow}>
<InfoBlock title="posts" value="128" />
<InfoBlock title="followers" value="256" />
<InfoBlock title="following" value="184" />
</View>
<View>
<Button title="Edit Profile" />
</View>
</View>
</View>
You are missing one more wrapper column view
<View>
<StatusBarBackground />
<View style={styles.user_profile}>
//Make this container something like flex:0.2
<View style={styles.container}>
<Image style={styles.image} source={require('./images/user_profile.jpg')}/>
</View>
// You need another column view wrapper
<View style={{flex:0.8}}>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.container}>
<Text style={styles.numbers}>128</Text>
<Text style={styles.grey_text}>posts</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>256</Text>
<Text style={styles.grey_text}>followers</Text>
</View>
<View style={styles.container}>
<Text style={styles.numbers}>184</Text>
<Text style={styles.grey_text}>following</Text>
</View>
</View>
<View style={styles.btnContainer}>
<Button title="Edit Profile" color="#000" backgroundColor="#CCC" raised={true} onPress={this.onPressEditProfile} />
</View>
</View>
</View>
</View>