text above row of buttons in React Native - react-native

This should be relatively easy for a React Native expert. I simply wish to display some text, and then under the text should be a row of buttons. Beginning with the row of buttons, this seems to work fine:
constructor(props) {
super(props);
this.state = {
titleText: "Bird's Nest",
bodyText: "This is not really a bird nest."
};
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button title="Camera"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Start"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Website"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Stop"/>
</View>
</View>
); //return
} //render
const styles = StyleSheet.create({
page:{
flex:1,
backgroundColor: "#000",
paddingTop:50,
color: 'white'
},
container: {
flex: 1,
backgroundColor: "#000",
flexDirection: 'row',
alignItems: 'center',
justifyContent: "center"
},
buttonContainer: {
flex: 1,
},
container1: {
backgroundColor: 'powderblue',
height : 100
},
container2: {
backgroundColor: 'grey',
height : 100
},
baseText: {
fontFamily: "Cochin"
},
titleText: {
fontSize: 20,
fontWeight: "bold",
color: 'white'
}
});
When I attempt to add the text...it is functional however the text is positioned before the row of buttons instead of placement over/above the row of buttons. Here is the same code inclusive of the text:
...
render() {
return (
<View style={styles.container}>
<Text style={styles.baseText}>
<Text style={styles.titleText} onPress={this.onPressTitle}>
{this.state.titleText}
{"\n"}
{"\n"}
</Text>
<Text numberOfLines={5}>{this.state.bodyText}</Text>
</Text>
<View style={styles.buttonContainer}>
<Button title="Camera"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Start"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Website"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Stop"/>
</View>
</View>
); //return
} //render
...
So basically the 'text' is rendered and then the 4 buttons are rendered with everything all 'crushed' together...all within the same row. There probably needs to be some sort of 'column' for the text however I have no idea how to combine 'column' and 'row' (necessary for the buttons) in React Native (within the same page 'container'). Or perhaps there is some other way to do it?
In addition, it would be nice if the row of buttons appeared along the bottom of the device screen instead of centered. I had changed the 'alignItems' in the 'styles.container' to 'baseline' (before I added any text) however that did not accomplish the desired result. I thank you in advance for any advice.
UPDATE:
At this point I have modified my code above and what I have now is something more along the lines of what I am seeking...although not perfect. There is probably a better way however here is what my code looks like now:
import BoxContainer from './BoxContainer';
render() {
return (
<View style={styles.page}>
<BoxContainer style={styles.container1}>
<Text>Bunch of text here.</Text>
</BoxContainer>
<BoxContainer style={styles.container2}>
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button title="Camera"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Start"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Website"/>
</View>
<View style={styles.buttonContainer}>
<Button title="Stop"/>
</View>
</View>
</BoxContainer>
</View>
); //return
} //render
The code for 'BoxContainer' is here, a resource I found on the Internet somewhere:
import React from 'react';
import { StyleSheet, View} from 'react-native';
const BoxContainer = props => {
return (
<View style={{...styles.boxContainer, ...props.style}}>
{props.children}
</View>
);
};
const styles = StyleSheet.create({
boxContainer:{
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.8,
shadowRadius: 2,
height:200,
margin: 20,
alignItems: 'center',
justifyContent: 'center'
}
});
export default BoxContainer;
As mentioned, this is close to what I am seeking however I wish I could find a way to do it without the structured box containers...or perhaps that is necessary in React Native...?

Related

React Native need <Text> to appear next to the pressable checkbox not inside

I need that the Text appears next to the pressable checkbox not inside it... How can i do this using styles and not changing the code structure?
return (
<Pressable
style={[{ opacity: disabled ? 0.5 : 1 },
styles.checkboxBase, checked && styles.checkboxChecked]}
onPress={onPress}>
<View style={[styles.checkboxContainer, style]}>
{checked && <Icon size={16} name="bullet"
color="gray" />}
</View>
<Text style={styles.text}>{label}</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
checkboxBase: {
width: 24,
height: 24,
},
checkboxChecked: {
justifyContent: "center",
alignItems: "center",
},
checkboxContainer: {
flexDirection: "row",
color: "red",
},
text: {},
});
Pressable is like a view with TouhcableOpacity. You have to put text and Pressable inside a partent probability in a view like this.
<View style={{flex-direction:'row'}}>
<Pressable>
<Icon />
</Pressable>
<Text></Text>
</View>

How to justify side-by-side buttons to centre with spacing between them?

My page currently!
Hi guys, I made these 2 buttons and I want them to be justified to the center, have rounded edges as well as have some spacing between them. This is my code currently:
export default class SortingComponent extends Component {
render() {
return (
<ScrollView>
<View>
<Text style = {styles.heading}>
Find Clinics By:
</Text>
</View>
<View style={{ flexDirection:"row" }}>
<View style = {styles.buttonStyle}>
<Button
title="Total Time"
onPress = {() => console.log("Sort by Total Time")}
>Total Time</Button>
</View>
<View style = {styles.buttonStyle}>
<Button
title="Travel Time"
onPress = {() => console.log("Sort by Travel Time")}
>Travel Time</Button>
</View>
</View>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
buttonStyle: {
fontSize: 20,
fontWeight: "bold",
alignItems: "center",
},
heading: {
fontSize: 35,
fontWeight: "bold",
}
});
Add justify-content : 'space-evenly' in view like
<View style={{ flexDirection:"row", justify-content : 'space-evenly'}}>
.....
</View>

React Native Components disappear on re-render

My app has a homescreen built out of hexagons. Since flex doesn't handle diagonal alignment well I used the transform prop to move the hexagons manually into alignment. However, when the app is re-rendered, the hexagons seem to disappear and reappear at random. It usually takes ~8 renders and then the hexagons will all magically reappear.
EDIT: The invisible hexagons can still be pressed, and when the user navigates back to the homescreen, all the hexagons are visible.
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Dimensions, TouchableOpacity } from 'react-native';
class Home extends Component {
constructor(props){
super(props);
}
render() {
return (
<View style={style.columnHexView}>
<View>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/logo.png')} />
</TouchableOpacity>
</View>
<View>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-2.5},
{translateX:(Dimensions.get('window').height/10)*-.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("documentList")}
>
<Image style={style.Hex}source={require('./images/documenthex.png')} />
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-3.5},
{translateX:(Dimensions.get('window').height/10)*.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("Settings")}
>
<Image style={style.Hex}source={require('./images/cog.png')} />
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-5}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
onPress={() => this.props.navigation.navigate("ToDo")}
>
<Image style={style.Hex}source={require('./images/todohex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-4.5},
{translateX:(Dimensions.get('window').height/10)*.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
<View style={{transform:([
{translateY:(Dimensions.get('window').height/10)*-5.5},
{translateX:(Dimensions.get('window').height/10)*-.84}
])}}>
<TouchableOpacity
activeOpacity = {.5}
style={style.HexOpacity}
>
<Image style={style.Hex}source={require('./images/emptyhex.png')}/>
</TouchableOpacity>
</View>
</View>
);
}
}
const style = StyleSheet.create({
columnHolder: {
flex: 0,
height: Dimensions.get('screen').height,
width: Dimensions.get('screen').width,
backgroundColor: '#424242',
flexDirection: 'row',
},
columnHexView: {
backgroundColor:'#424242',
alignItems: "center",
justifyContent: 'center',
flex: 1,
},
Hex: {
aspectRatio: 100/85,
maxHeight: Dimensions.get('window').height/10,
resizeMode: 'contain',
flexDirection: 'column',
flex: 0,
flexWrap: 'wrap'
},
hexHold:{
},
HexOpacity: {
justifyContent: 'center',
resizeMode: 'stretch',
display: 'flex',
maxHeight: Dimensions.get('window').height/5
}
}
)
export default Home
In case anyone sees this, the solution was to use cover resize mode instead of contain. I suspect that it was only rendering some hexagons due to slight overlap in between the hexagons.

Vertical text in react native is cut by it's original height (using transform)

I have the following code in which I would like the black boxed text to be placed vertically, either centered or aligned to the top, and be cut by the end of the corresponding text view (sample text).
It seems like even though the text is transformed, it still measures its original height and thus shows only the first letter with ...
adding width:50 to the transformed view, will show better results, but the number of lines in the sample text is changing (and also the font sizes).
this is the result I'm getting:
And this is the required result (using paint.net ;)):
Does anyone have an idea how to do it?
Thanks!
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
class SideComponent extends Component{
render(){
return (
<View style={{flex:1, alignItems:'center', justifyContent:'center', borderColor:'black', borderWidth:0.5, width:20,}}>
<View style={{transform: [{ rotate: '90deg'}]}}>
<Text numberOfLines={1} style={{borderColor:'blue'}}>{this.props.text}</Text>
</View>
</View>
)
}
}
class LineComponent extends Component{
render(){
return (
<View style={{flex:1}}>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
<Text numberOfLines={2} style={{backgroundColor:'yellow'}}>Sample text</Text>
</View>
)
}
}
export default class App extends Component{
render() {
return (
<View style={styles.container}>
<View style={{flexDirection:'row'}}>
<SideComponent text="Short"/>
<LineComponent/>
</View>
<View style={{flexDirection:'row'}}>
<SideComponent text="LongTextLong" style={{}}/>
<LineComponent/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
flexDirection: 'column',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
I tried something like this for vertical transformation:
<View style={{flexDirection:'row'}}>
<View style={{flex:0.1 }}>
<View style={{left:-130,width:300,height:20,alignItems:'flex-start',justifyContent:'flex-start',transform: [{ rotate: '270deg'}]}}>
<Text numberOfLines={1} style={[AppStyles.regularFontText,{fontSize:12,color:'#8160e5'}]}>Number of Users</Text>
</View>
</View>
<View style={{flex:0.9}}>
<BarChart
style={{height:200,width:width-100[enter image description here][1]}}
data={this.state.line_data}
chartDescription={{ text: '' }}
xAxis={this.state.xAxis}
animation={{durationX: 2000}}
legend={this.state.line_legend}
gridBackgroundColor={processColor('#ffffff')}
drawBarShadow={false}
drawValueAboveBar={true}
drawHighlightArrow={true}
onSelect={this.handleSelect.bind(this)}
highlights={this.state.highlights}
onChange={(event) => console.log(event.nativeEvent)}
/>
</View>
</View>

How to vertically aligned my image to top in my React-native component

I'd like to top aligned my image in React-native. But don't know what to do. Here is my layout and its style:
class layout extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.toolbar}>
<Text style={styles.left}>
Left Button
</Text>
<Text style={styles.title}>
This is my title
</Text>
<Text style={styles.right}>
Right Button
</Text>
</View>
<View style={styles.content}>
<Image style={styles.image}
source={require('./back.jpg')}
resizeMode="contain"
></Image>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
toolbar: {
backgroundColor: '#B5AC3a',
height:64,
flexDirection:'row'
},
left: {
marginTop:30,
fontSize: 14,
textAlign: 'center'
},
right: {
marginTop:30,
fontSize: 14,
textAlign: 'center'
},
title: {
marginTop:30,
flex: 1,
fontSize: 14,
textAlign: 'center'
},
content: {
backgroundColor:'#ffecff'
},
image: {
width: Dimensions.get('window').width - 20,
margin: 10,
alignSelf:'center'
}
});
Here is the result:
Apparently there are a lot of space between my image to top of my screen. I tried: flex-start. But doesn't work. What should I do? Thanks.
P.S: It's fine if I use View instead of Image like this:
class layout extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.toolbar}>
<Text style={styles.left}>
Left Button
</Text>
<Text style={styles.title}>
This is my title
</Text>
<Text style={styles.right}>
Right Button
</Text>
</View>
<View style={styles.content}>
<View style={styles.messageBox}>
<Text>This is line one</Text>
<Text>This is line two</Text>
</View>
</View>
</View>
);
}
}
Result:
Your resizeMode='contain' on your image is conflicting with the dimensions you want to define in styles.image.
Simply remove resizeMode='contain' in your <Image> properties and it should work.
Something else: I would strongly advise you, depending on what you're trying to do, to use a ScrollView instead of the simple View when you have extendable content (namely anything that isn't completely static). This seems to be what you need.