<SafeAreaView> not work (Views go above the notification tab) - react-native

For some reason safeAreaView does not work in my code, Views go above the notification tab. I've tried a few things but couldn't. I tried to take the style of safeAreaView and create a view below safeAreaView that involves all the code and then in that view put that style, but it didn't work either!
import React from 'react';
import { SafeAreaView, StyleSheet, View, Image, Text } from 'react-native';
export default function Menu({ navigation }){
return <SafeAreaView style={styles.container}>
<View style={styles.profile}>
<Image source={{uri: 'https://elysator.com/wp-content/uploads/blank-profile-picture-973460_1280-e1523978675847.png'}} style={styles.imageProfile} />
<Text style={styles.name}>StackOverFlow</Text>
</View>
</SafeAreaView>
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
profile: {
flexDirection: 'row',
backgroundColor: '#EEE',
},
imageProfile: {
width: 34,
marginBottom: 5,
marginTop: 5,
borderRadius: 44/2,
marginLeft: 10,
height: 34
},
name: {
alignSelf: 'center',
marginLeft: 10,
fontSize: 16
}
});

According to react-native docs:
The purpose of SafeAreaView is to render content within the safe area
boundaries of a device. It is currently only applicable to iOS devices
with iOS version 11 or later.
I would advise you to not just follow safeAreaView functionalities. rather its better extract the Status bar height and give a marginTop to whole container so its always below the status bar. See the code below and also the working expo snack solution:
import React from 'react';
import { SafeAreaView, StyleSheet, View, Image, Text,StatusBar } from 'react-native';
export default function Menu({ navigation }){
return <SafeAreaView style={styles.container}>
<View style={styles.profile}>
<Image source={{uri: 'https://elysator.com/wp-content/uploads/blank-profile-picture-973460_1280-e1523978675847.png'}} style={styles.imageProfile} />
<Text style={styles.name}>StackOverFlow</Text>
</View>
</SafeAreaView>
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop:StatusBar.currentHeight
},
profile: {
flexDirection: 'row',
backgroundColor: '#EEE',
},
imageProfile: {
width: 34,
marginBottom: 5,
marginTop: 5,
borderRadius: 44/2,
marginLeft: 10,
height: 34
},
name: {
alignSelf: 'center',
marginLeft: 10,
fontSize: 16
}
});
Expo link :expo-snack
Hope it helps. feel free for doubts

The SafeAreaView from 'react-native-safe-area-context' just worked for me.

The react-native version doesn't work on Android or early iOS versions.
Specifically you want to use:
import { SafeAreaView } from 'react-native-safe-area-context'
and not
import { SafeAreaView } from 'react-native'
If you're not already using react-native-safe-area-context then you might want to read the documentation as it also requires that you use the SafeAreaProvider component at a higher level in your app.

Try "resizeMode" in imageview
enum('cover', 'contain', 'stretch', 'repeat', 'center')
https://facebook.github.io/react-native/docs/image#resizemode

None of these work for me ,
so i try this and it solve the problem.
First: Import SafeAreaProvider from react-native-safe-area-context as shown below.
import { SafeAreaProvider} from 'react-native-safe-area-context';
Second : give marginTop to it, in my case is was 13%, adjust according to your needs, as shown below .
<SafeAreaProvider style={{marginTop:"13%"}} >
<Home/>
...
<SafeAreaProvider/>
Let me know if this was helpful.

Related

Can not find attributed text in react native

I want to display an image, attributed text inside Text programmatically, but after reading React Native document I cannot find anything that related to attributed text.
In Android, it's called SpannableString, and it's equevalent to AttributedString in iOS, but I cannot find the same in React Native.
Can anyone guide me some great library/document?
Try this package react-native-spannable-string
your question is unclear but if i've gotten it correctly you want to display text on top of an image. If thats the case use Imagebackground
import React from "react";
import { ImageBackground, StyleSheet, Text, View } from "react-native";
const image = { uri: "https://reactjs.org/logo-og.png" };
const App = () => (
<View style={styles.container}>
<ImageBackground source={image} resizeMode="cover" style={styles.image}>
<Text style={styles.text}>The text you want to display</Text>
</ImageBackground>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
},
image: {
flex: 1,
justifyContent: "center"
},
text: {
color: "white",
fontSize: 42,
lineHeight: 84,
fontWeight: "bold",
textAlign: "center",
backgroundColor: "#000000c0"
}
});
export default App;

My first react native code in expo: need to add splash screen with 5 seconds time

This is my first expo code which I am able to run successfully:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import { WebView } from 'react-native-webview';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
return (
<WebView
style={{ marginTop: 0 }}
source={{ uri: 'https://baldeaglemall.com/' }}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
But I am unable to add a splash screen with 10 seconds time to it for display. Chasing google search is not leading me anywhere. What modifications do I need to do my code above?
Edit:
Splash screen works based on examples in expo documentation.
But the below answer causes a white screen right after the splash screen and it stays at white screen and never goes in the webview.
You could use SplashScreen.preventAutoHideAsync() (provided by expo-splash-screen) to make the native splash screen stay visible until SplashScreen.hideAsync() is called.
Add the package to your dependencies
$ expo install expo-splash-screen
And then, use it like this:
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import { WebView } from 'react-native-webview';
import * as SplashScreen from 'expo-splash-screen'; // <-- import it
import AssetExample from './components/AssetExample';
import { Card } from 'react-native-paper';
// Prevent native splash screen from autohiding before App component declaration
SplashScreen.preventAutoHideAsync()
.then((result) => console.log(`SplashScreen.preventAutoHideAsync() succeeded: ${result}`))
.catch(console.warn); // it's good to explicitly catch and inspect any error
export default function App() {
React.useEffect(() => {
setTimeout(async () => {
await SplashScreen.hideAsync();
}, 5000); // <-- Set this to `5000` ms to hide it after 5 seconds
}, []);
return (
<WebView
style={{ marginTop: 0 }}
source={{ uri: 'https://baldeaglemall.com/' }}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
Disclaimer: I haven't tested this code, but it should work

I'm trying to load all the images as a scrollable menu but can't figure out how

I'm new to react native, I am trying to get a menu composed of logos that someone could just scroll down then tap one to go into more detail about it.
So I have my App.js file like so:
import React from 'react';
import {
StyleSheet,
View,
Image,
ScrollView,
Text
} from 'react-native';
import getImageForRestaurant from './utils/getImageForRestaurant';
import Avatar from './components/Avatar';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
restaurants: 'buffalo',
};
}
render() {
const {
restaurants
} = this.state;
return (
<View style={styles.appContainer}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Title</Text>
</View>
<ScrollView style={styles.timerlist}>
<Avatar
initials="KC"
size={75}
source={getImageForRestaurant(restaurants)}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
appContainer: {
flex: 1,
justifyContent: 'center',
},
titleContainer: {
paddingTop: 35,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: '#D6D7DA',
},
title: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
timerList: {
paddingBottom: 15,
},
container: {
flex: 1,
backgroundColor: '#34495E',
},
imageContainer: {
flex: 0,
},
image: {
flex: 1,
width: 75,
height: 75,
resizeMode: 'contain',
},
});
The getImageForRestaurant() method works as intended if I make it inside an <Image/> but if I try to make it the source of my "Avatar" component then it won't work.
My getImageForRestaurant.js file is just this:
const images = {
buffalo1: require('../assets/restaurants/logo1.jpeg'),
buffalo: require('../assets/restaurants/logo2.png'),
buffalo2: require('../assets/restaurants/logo3.jpeg'),
};
export default restaurants => images[restaurants];
And finally my Avatar.js is as follows:
import {
ColorPropType,
StyleSheet,
Text,
View,
Image,
TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';
import React from 'react';
import getImageForRestaurant from '../utils/getImageForRestaurant';
export default function Avatar({
size,
backgroundColor,
initials,
source,
onPressLinkImage,
}) {
const style = {
width: size,
height: size,
borderRadius: size / 2,
backgroundColor,
};
return (
<View style={[styles.container, style]}>
<TouchableOpacity onPress={onPressLinkImage}>
<Text style={styles.text}>{initials}</Text>
<Image source={require(getImageForRestaurant(source))} />
{/*<Image source={require("../assets/restaurants/logo1.jpeg")} />*/}
</TouchableOpacity>
</View>
);
}
Avatar.propTypes = {
initials: PropTypes.string.isRequired,
size: PropTypes.number.isRequired,
source: PropTypes.number.isRequired,
backgroundColor: ColorPropType.isRequired,
onPressLinkImage: PropTypes.func.isRequired,
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
justifyContent: 'center',
},
text: {
color: 'white',
},
});
So if I just do an Image source, (the commented part) it works as a regular image, but then I need to hard-code the actual url and what I want is to just load all images one next to the other in a scrollable grid. Haven't been able to figure out how to do what I want. Could someone please point me in the right direction?
While Edison makes a good point about good practices, I believe your problem is that you are just requiring the image twice. The output of the require() is what you need to pass to the Image component. You are doing require of a require.
<Image source={require(getImageForRestaurant(source))} />
Probably just changing to this should work:
<Image source={getImageForRestaurant(source)} />
It’s a bad practice to generate url inside the source prop. Always make sure that the necessary URL is built before its passed inside source prop. You can use a variable to build your URL and then pass it to source prop. (In your case, image is imported inside helper function and hence I will use image variable)
const image = getImageforRestaurant(source)
<Image source={image} />
When you want to load images from the internet do it like this.
const link = ‘http://example.com/image.png’
<Image source={{uri: link}} />

React Native SMS module

I want to be able to send a SMS from a react native application natively withou open the actually sms application on ios or android. Does anyone know of any was of making this happen without without using a API such as twilio or Nexmo?
You can use this package react-native-sms-android
But it only works for Android.
You can use the react-native-sms-x package.
You just need to add this project in setting.gradle and build.gradle files. then the below code
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import SendSMS from 'react-native-sms-x';
export default class RNSMS extends Component {
sendSMSFunction() {
SendSMS.send(123, "+95912345678", "Hey.., this is me!\nGood to see you. Have a nice day.",
(msg)=>{
ToastAndroid.show(msg, ToastAndroid.SHORT);
}
);
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={this.sendSMSFunction.bind(this)}>
<Text>Send SMS</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button: {
padding: 10,
borderWidth: .5,
borderColor: '#bbb',
margin: 10,
alignItems: 'center',
justifyContent: 'center'
}
});
AppRegistry.registerComponent('RNSMS', () => RNSMS);
For more info refer https://www.npmjs.com/package/react-native-sms-x

KeyboardAwareScrollView Works For iOS But Not For Android And Seems To Mess Up Layout On Android

I'm very new to React-Native and have been playing around with trying to automatically adjust the views based on the keyboard showing or disappearing.
I have employed the tag (and module) and it works exactly the way it is supposed to on the iOS simulator, but on the android emulator it doesn't show my entire logo and the textFields are nowhere to be found. The code is the same in both the index files for android and iOS so i'm a bit stuck on this one. Images below:
====== iOS Screenshot ======
iOS Simulator Login Screen Screenshot
====== Android Emulator Screensho ======
Android Emulator Login Screen Screenshot
Is there something that i'm doing wrong or missing?
Below is my code for the login/launch/home screen including my styling/stylesheets.
import React, { Component } from 'react';
import { AppRegistry, Text, View, Image, StatusBar, ScrollView, KeyboardAvoidingView, Keyboard } from 'react-native';
import Dimensions from 'Dimensions';
import TextField from 'react-native-md-textinput';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
let window = Dimensions.get('window');
class MainApp extends Component {
constructor() {
super();
this.state = {}
}
render(){
return (
<View style={styles.contentContainerStyle}>
<StatusBar barStyle = "light-content" hidden = {false} />
<KeyboardAwareScrollView extraHeight={80}>
<Image style={styles.ctfLondonLogoStyle} source={require('../images/ctflondon.png')}/>
<View style={styles.usernameTextFieldPositioningStyle}>
<TextField style={styles.textFieldStyles}
dense={true}
label='Username'
labelColor='white'
highlightColor='white'
borderColor='white'
fontSize={13}
selectionColor='white'
/>
</View>
<View style={styles.passwordTextFieldPositioningStyle}>
<TextField
dense={true}
label='Password'
labelColor='white'
highlightColor='white'
borderColor='white'
fontSize={13}
selectionColor='white'
secureTextEntry={true}
/>
</View>
</KeyboardAwareScrollView>
</View>
)
}
}
const styles = {
contentContainerStyle: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'rgba(190,0,39,0.7)'
},
mainScrollViewStyle: {
},
ctfLondonLogoStyle: {
alignSelf: 'center',
top: 150,
width: 150,
height: 150
},
textFieldStyles: {
width: 150,
height: 35,
color: 'white'
},
usernameTextFieldPositioningStyle: {
position: 'relative',
width: window.width * 0.55,
alignSelf: 'center',
top: 180
},
passwordTextFieldPositioningStyle: {
position: 'relative',
width: window.width * 0.55,
alignSelf: 'center',
top: 200
}
};
export default MainApp;