Conditional component rendering using switch - react-native

I have created 3 buttons in react native. I have stored images in three different components. I want that when i click on first button, it show the image stored in first component and so on . I want to use switch case statement. I dont want to use any library like tab navigators.
app.js
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
Button,
TouchableOpacity
} from "react-native";
import first from "./components/first";
import second from "./components/second";
import third from "./components/third";
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.wrapper1}>
<Text>Button 1</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.wrapper2}>
<Text>Button 2</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.wrapper3}>
<Text>Button 3</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5FCFF",
alignItems: "flex-start",
flexDirection: "row"
},
wrapper1: {
borderWidth: 1,
borderColor: "black",
backgroundColor: "red",
paddingHorizontal: 40,
paddingVertical: 15
},
wrapper2: {
borderWidth: 1,
borderColor: "black",
backgroundColor: "red",
paddingHorizontal: 40,
paddingVertical: 15
},
wrapper3: {
borderWidth: 1,
borderColor: "black",
backgroundColor: "red",
paddingHorizontal: 40,
paddingVertical: 15
}
});
first.js
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
Button,
TouchableOpacity
} from "react-native";
export default class first extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Image
source={{ uri: "http://facebook.github.io/react/img/logo_og.png"
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5FCFF",
alignItems: "flex-start",
flexDirection: "row"
}
});
second.js
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
Button,
TouchableOpacity
} from "react-native";
export default class second extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Image
source={{ uri: "http://facebook.github.io/react/img/logo_og.png"
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5FCFF",
alignItems: "flex-start",
flexDirection: "row"
}
});
third.js
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
Button,
TouchableOpacity
} from "react-native";
export default class third extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Image
source={{ uri: "http://facebook.github.io/react/img/logo_og.png"
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5FCFF",
alignItems: "flex-start",
flexDirection: "row"
}
});

A clean way consist in :
Storing the pictures url in an array
Use a state to keep the current picture index
Call one time the Image component, with a different url depending of the state
Add buttons to change the state
I created a working example :
https://snack.expo.io/#sanjar/so-53608978
Edit : if you really want to keep different components, and to use a switch here is a working example :
https://snack.expo.io/#sanjar/so-53608978-2

Related

How to properly set the backgroundColor for a screen imported in React-native?

i still learning react-native and want to set the backgroundColor to an entire screen which is imported in app.js.
Even if i set the flex in 1, the height covering the screen but the width is always center but not covering the entire screen.
Here what i'm doing:
App.js
import { StatusBar } from "expo-status-bar";
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import Splash from "./Screen/Splash";
import TestScreen from "./Screen/TestScreen";
export default function App() {
return (
<View style={styles.container}>
{/* <Splash /> */}
<TestScreen />
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
// flexDirection: "column",
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
TestScreen.js:
import React from "react";
import { View, Text, StyleSheet } from "react-native";
const Test = () => {
return (
<View style={styles.container}>
<Text>Hello</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgb(0, 168, 150)",
},
});
export default Test;
So,how i can set properly the backgroundColor to ScreenTest to cover the entire screen?
Thanks
Within app.js maybe add the full-width property:
<TestScreen style = {styles.redbox} >
container: {
flex: 1
},
redbox: {
width: 100,
height: 100,
backgroundColor: 'red'
},

How do you use flex inside a scrollView React Native

When I use the ScrollView with contents that have flex they don't show and flex doesn't seem to work. How do you get flex to work inside a ScrollView?
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
ScrollView,
TouchableOpacity,
Dimensions,
} from 'react-native';
const App = (props) => {
return (
<ScrollView style={styles.body}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</ScrollView>
);
};
const styles = StyleSheet.create({
body: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#fff',
borderColor: 'red',
borderWidth: 5
},
box1: {
flex: 1,
backgroundColor: 'blue',
},
box2: {
flex: 2,
backgroundColor: 'purple',
}
});
export default App;
I've created a snack. The inner views/boxes don't show.
I managed to figure it out. You create another view inside the scrollView and fix the height. The only problem is that the size of the content views depends on the height of this view instead of the height of the scrollView.
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
ScrollView,
TouchableOpacity,
Dimensions,
} from 'react-native';
// import { useHeaderHeight } from '#react-navigation/stack';
const App = (props) => {
let screenHeight = Dimensions.get('window').height;
// let headerHeight = useHeaderHeight();
let headerHeight = 0
let bodyHeight = screenHeight - headerHeight + 500;
return (
<ScrollView style={styles.body}>
<View style={[styles.innerBody, { height: bodyHeight }]}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
body: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#fff',
},
innerBody: {
borderColor: 'red',
borderWidth: 5
},
box1: {
flex: 1,
backgroundColor: 'blue',
},
box2: {
flex: 2,
backgroundColor: 'purple',
}
});
export default App;
Heres a snack showing it working.

How to position a child component in react native

I am trying to position my bottomnavbar to the bottom of my screen, but is is not working?
I've been trying to set the position to absolute and then bottom: 0, but if I do it in the app.js component on or do it straight in the stylesheet of the bottomNavbar.js component, none of it works.
here is my app.js component:
import React, {Component} from 'react';
import {View, Text, StyleSheet} from 'react-native';
class BottomNavbar extends Component {
render() {
return (
<View style={styles.container}>
<Text>insights</Text>
<Text>Incidents</Text>
<Text>PLUS</Text>
<Text>Team Alerts</Text>
<Text>More</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'grey',
position: 'absolute',
bottom: 0,
},
});
export default BottomNavbar;
And here is my BottomNavbar component:
import React, {Component} from 'react';
import {View, Text, StyleSheet} from 'react-native';
class BottomNavbar extends Component {
render() {
return (
<View style={styles.container}>
<Text>insights</Text>
<Text>Incidents</Text>
<Text>PLUS</Text>
<Text>Team Alerts</Text>
<Text>More</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'grey',
position: 'absolute',
bottom: 0,
},
});
export default BottomNavbar;
Now I would like the bottomnavbar to show up at the bottom of the phonescreen, but I cannot figure out how to do that.
Try this one
import { AppRegistry } from 'react-native';
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
class BottomNavbar extends Component {
render() {
return (
<View style={styles.container}>
<Text>insights</Text>
<Text>Incidents</Text>
<Text>PLUS</Text>
<Text>Team Alerts</Text>
<Text>More</Text>
</View>
);
}
}
class App extends Component {
render() {
return (
<View style={styles.appContainer}>
{/* ...other components */}
<BottomNavbar />
</View>
);
}
}
const styles = StyleSheet.create({
appContainer: {
flex: 1,
},
container: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'grey',
position: 'absolute',
bottom: 0,
width: '100%',
height: 80,
},
});
AppRegistry.registerComponent('myApp', () => App);

background color in cardview title (react-native)

I am trying to create a cardview in react-native with a title and body. however, i want to add a background color to the tittle but not able to do it.
i was able to create the cardview with a title header but not able to add a background color that covers the entire portion of the header.
see image attached for an example of what i want to implement.
As you can see, the card view has a tittle of summary and the title/header portion has a gray background. below the header is the body which contain the content of the cardview. i want to implement the same in react-native. can someone help? thanks in advance
//This is an example of Card View//
import React from 'react';
//import react in our code.
import { Text, View, StyleSheet } from 'react-native';
//import all the components we are going to use.
import { Card } from 'react-native-elements';
//import Card
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Card title="Local Modules">
{/*react-native-elements Card*/}
<Text style={styles.paragraph}>
This is a card from the react-native-elements
</Text>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: 40,
backgroundColor: '#ecf0f1',
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
Try this:
<Card title={
<View style={{ backgroundColor: 'red'}}>
<Text>Local Modules</Text>
</View>
}
...
/>
Edit your code like this :
//This is an example of Card View//
import React from 'react';
//import react in our code.
import { Text, View, StyleSheet } from 'react-native';
//import all the components we are going to use.
import { Card } from 'react-native-elements';
//import Card
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Card title="Local Modules">
<View style={styles.header}>
<Text> Summary </Text>
</View>
<Text style={styles.paragraph}>
This is a card from the react-native-elements
</Text>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: 40,
backgroundColor: '#ecf0f1',
},
header: {
backgroundColor : '#C4C4C4'
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});

Text wrap with chevron on right in React Native ListView item renderer

I am trying to have a list view show up that looks similar to this. The problem I am trying to solve is regarding word wrapping of the label. I do have it working with the code below, but it feels like a hack and doesn't work with device rotation. There has to be a way to do it without using Dimensions and styling.
Here is what I have.
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={{width: Dimensions.get('window').width - 50}}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails}>{`${Moment(this.props.lastUpdated).fromNow()}`}</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The other option I tried was absolute positioning, with the label being 20px from the right, and then absolute positioning the chevron on the right. The problem I ran into there was trying to figure out the height of the individual listItem renderer after it is rendered (and word wrapped).
The problem comes from having flexDirection: 'row' in the View containing your text. This makes the text overflow to the right instead of wrapping. If you want your text to wrap, the containing View must have flexDirection: 'column' in the style.
I've modified your code accordingly:
import React, { Component } from 'react';
import {
StyleSheet,
Dimensions,
TouchableOpacity,
Text,
View
} from 'react-native';
import Moment from 'moment'
import Icon from 'react-native-vector-icons/FontAwesome';
class ProjectListItemRenderer extends Component {
componentDidMount() {
//alert(Dimensions.get('window').height)
}
render() {
return (
<View style={styles.projectRow}>
<View style={styles.projectText}>
<Text style={styles.itemName}>{this.props.name}</Text>
<Text style={styles.itemDetails>
{`${Moment(this.props.lastUpdated).fromNow()}`}
</Text>
</View>
<View style={styles.moreContainer}>
<Icon name="chevron-right" size={15} style={styles.moreIcon} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
projectText: {
flex: 1,
flexDirection: 'column'
},
projectRow: {
flexDirection: 'row',
justifyContent: 'flex-start',
padding: 15,
},
itemName: {
fontSize: 18,
color: '#4A90E2',
},
itemDetails: {
fontSize: 12,
color: '#BBBBBB',
},
moreContainer: {
justifyContent: 'center',
alignItems: 'center'
},
moreIcon: {
color: "#d6d7da"
}
});
module.exports = ProjectListItemRenderer;
The only difference is I replaced {width: Dimensions.get('window').width - 50} with {flex: 1, flexDirection: 'column'}.