How do I Flex a Safeview properly? - react-native

So I am trying to add a view inside of a Safeview. But the Flex option in the SafeView is not allowing me to add the view.
if I remove the flex, it cuts off at the bottom of the screen.
How do I resolve this?
import React from "react";
import Constants from "expo-constants";
import { StyleSheet, SafeAreaView, View } from "react-native";
function Screen({ children, style }) {
return (
<SafeAreaView style={[styles.screen, style]}>
<View style={style}>{children}</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
screen: {
paddingTop: Constants.statusBarHeight,
flex: 1
},
});
export default Screen;

We can put Vỉew into the SafeAreaView. I guess props of style parameter when passing to this children has something incorrect.
Sample styles:
container: {
flex: 1,
alignItems: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#fefefe',
}
And the children view:
<SafeAreaView style={styles.container}>
<IconsTitleHeader title={'Go Back'} navigation={this.props.navigation} />
<View style={styles.mainContainer}>
<Text>{"No internet connection"}</Text>
</View>
</SafeAreaView>

Related

How to get a param of an id using react-navigation v5?

I'm trying to update an app I've developed using react-navigation v4.
Using react-navigation v4 I could get the id using something like console.log(navigation.getParam('id'));
But when I tried the same after updating to v5 of react-navigation it shows me an error and I can't find the right way to get the param id
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation }) {
console.log(navigation.getParam('id'));
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
The other screen where the id is located is it:
import React, { useContext } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import { Context } from '../../context/BlogContext';
import Icon from 'react-native-vector-icons/Feather'
export default function IndexScreen({ navigation }) {
const { state, addBlogPost, deleteBlogPost } = useContext(Context);
return (
<View style={styles.container}>
<Button
title="Add Post"
onPress={addBlogPost}
/>
<FlatList
data={state}
keyExtractor={(blogPost) => blogPost.title}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={
() => navigation.navigate('ShowScreen',
{ id: item.id })}>
<View style={styles.row}>
<Text style={styles.title}>
{item.title} -
{item.id}
</Text>
<TouchableOpacity onPress={() => deleteBlogPost(item.id)}>
<Icon style={styles.icon}
name="trash"
/>
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 30,
justifyContent: 'center',
alignItems: 'center'
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#333'
},
title: {
fontSize: 18
},
icon: {
fontSize: 24
}
});
You can get params using route.params in react navigation v5 more on that read here
just update your code to this
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation,route }) {
const {id} =route.params; //you will get id here via route
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
you can simply access your parameters like this
const id = this.props.route.params.id
inside this.props.route.params you will get all paramaters :)

How to move content to right side using flexbox in React native

I am working on React native, In my project In one View tag I have two Text tags how to move the second text tag to the right side using flex box. But I have to move it to the right side by only using flex box not padding or margin
This is App.js
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
const App = () => {
return (
<View style={styles.container}>
<Text>Hello World</Text>
<Text>Welcome</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
paddingRight: 10,
paddingLeft: 10,
},
});
export default App;
justifyContent: 'space-between' will evenly space all the child components, with the first and last ones on the corresponding ends.
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
const App = () => {
return (
<View style={styles.container}>
<Text>Hello World</Text>
<Text>Welcome</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingRight: 10,
paddingLeft: 10,
},
});
export default App;
Check the React Native documentation on any topic, it's quite good:
https://reactnative.dev/docs/flexbox
You can simply add a style to the container like this:
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-between', //this will push them to left and right
paddingRight: 10,
paddingLeft: 10,
},
});
Or if you want to simply specify that you want that specific element to the right you can use justifyContent: 'flex-end'
const App = () => {
return (
<View style={styles.container}>
<Text>Hello World</Text>
<Text style={{justifyContent: 'flex-end'}}>Welcome</Text>
</View>
);
};

Can't Wrap Navigator in SafeAreaView

When running the app on the iPhone X simulator the Material Top Tab Navigator cuts into the notch and bottom button.
To fix this I have tried to implement the SafeAreaView before applying the App Container and to wrap each individual screen in SafeAreaViews. This works to keep the text away from these areas but not the navigator.
import React, { Component } from 'react';
import { Text, View } from 'react-native';
import { createAppContainer, createMaterialTopTabNavigator, SafeAreaView } from 'react-navigation';
class Calculator extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Calculator!</Text>
</View>
);
}
}
class Camera extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Camera!</Text>
</View>
);
}
}
class Solution extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Solution!</Text>
</View>
);
}
}
const TabNavigator = createMaterialTopTabNavigator(
{
Calculator,
Camera,
Solution
},
{
tabBarPosition: 'bottom',
}
);
const AppContainer = createAppContainer(TabNavigator);
class App extends Component {
render() {
return (
<SafeAreaView>
<AppContainer/>
</SafeAreaView>
);
}
}
export default App;
When running this application, no errors are present. However, nothing renders. What I would expect is a tab navigator renders with three tabs that doesn't cut under the notch or bottom button.
give SafeAreaView a size
<SafeAreaView style={{ flex: 1 }}>
<AppContainer/>
</SafeAreaView>
if AppContainer still spreads full screen,
change import { SafeAreaView } from 'react-navigation'
to import { SafeAreaView } from 'react-native'
You need to provide flex: 1 as style to the SafeAreaView Component
<SafeAreaView style={{flex: 1}}>
{/* Component here */}
</SafeAreaView>

Conditional component rendering using switch

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

Expo xde not using style

When I run following code in the sandbox https://snackexpo.io it works fine. But when I run from the Expo xde I get Invariant Violation: Scrollview child layout must be applied through the contentContainerStyle prop.
import React from 'react';
import { Button, StyleSheet, ScrollView } from 'react-native';
export default class App extends React.Component {
blockJS(){
const done = Date.now() + 5000
console.log('blocking')
while(Date.now() < done){done}
console.log('not blocking')
}
render() {
return (
<ScrollView style={styles.container}>
<Button title='Block js' onPress={()=> this.blockJS()}/>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'lightblue',
alignItems: 'center',
justifyContent: 'center',
}
})
ScrollView does not support alignItems and justifyContent unless it is passed as a contentContainerStyle or wrap your contents inside and pass the styles to them.
You can change it as follows
<ScrollView contentContainerStyle={styles.container}>
<Button title='Block js' onPress={()=> this.blockJS()}/>
</ScrollView>
Or as a wrapper
// flex will only be applied on contentContainer to get it inherited
<ScrollView contentContainerStyle={{flex: 1}}>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Some sample text</Text>
</View>
</ScrollView>