My react-native app look totally fine on most Android devices (and iOS) I tested on emulator, but some devices with noticeable curved screen on top (Google Pixel 4, API 29), it shows a big empty region on top of the phone.
This does not look normal. Do you know how to fix it ?
I am using SafeAreaView but without any Android specific padding/margin.
<SafeAreaView style={{flex:1}}>
... My App Code come here.
</SafeAreaView>
I also tried to remove the the SafeAreaView and used regular View instead but it still wont go away.
Just for testing I removed everything and added a hello world test screen.
It still gives same wide empty space.
My App.js:
export default class Main extends React.Component {
constructor(props) {
super (props);
}
render () {
return (
<View style={{flex:1, backgroundColor: 'white'}}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
AppRegistry.registerComponent(appName, () => Main);
You can't remove it, it's a display bug on the Pixel 4 emulator. A physical Pixel 4 doesn't have that gap.
See my other answer for a detailed explanation.
You can achieve this simply by hiding your StatusBar just like this:
import React from "react";
import { StatusBar, View, Text } from "react-native";
export default class Main extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
StatusBar.setHidden(true);
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
Update: set StatusBar's transluent attribute to true along with make its' background as transparent like this:
import React, { Component } from "react";
import { StatusBar, View, Text } from "react-native";
export default class Main extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
StatusBar.setTranslucent(true);
StatusBar.setBackgroundColor("transparent");
}
render() {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<Text> Hello World, How to fix this ? </Text>
</View>
);
}
}
Have you tried using this way
<StatusBar translucent={true} hidden={true} /> {/* <--- Here */}
Check statusbar component where you can draw an app under the status bar by using the property named translucent. Reference link
I managed to fix this by going to AVD Manager -> Click on Wipe Data
Img
Related
Working thru a React Native tutorial and got to a part on Routing between various components. It looks like it doesnt like the "Menu" component and its asking, as the title says,
Is your component inside NavigationContainer?
As far as I can tell yes. I tried asking the author but this was on Pluralsight and I dont't think they've checked back in ages. I checked their code though, and it works just like I have it. So not sure what may have changed with the framework since that series was made.
Here is the full output when the error pops:
This error is located at:
in Menu (created by Home)
in RCTView (created by View)
in View (created by Home)
in RCTView (created by View)
in View (created by Home)
in Home (created by App)
in App
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in GloboTicket(RootComponent), js engine: hermes
The Menu component (minus StyleSheet)
import React from 'react';
import {View, TouchableOpacity, Text, StyleSheet} from 'react-native';
import {useNavigation} from '#react-navigation/native';
const Menu = () => {
const navigation = useNavigation();
return (
<View style={styles.menu}>
<TouchableOpacity
onPress={navigation.navigate('Tickets')}
style={styles.button}>
<Text style={styles.buttontext}>Events</Text>
</TouchableOpacity>
</View>
);
};
export default Menu;
Code from "Home" where the Menu is used (minus StyleSheet):
import React from 'react';
import {View, Image, Text, StyleSheet} from 'react-native';
import Menu from './Menu';
const Home = props => {
return (
<View style={styles.container}>
<Image
style={styles.globologo}
source={require('./images/globologo.png')}
/>
<Text style={styles.title}>Welcome to GloboTicket</Text>
<Text style={styles.subtitle}>{props.username}</Text>
<Image
style={styles.concertimage}
source={require('./images/concert.jpg')}
/>
<View style={styles.textcontainer}>
<Text style={styles.content}>{introText}</Text>
</View>
<View style={styles.menu}>
<Menu />
</View>
</View>
);
};
App file (where all lies within a NavigationContainer):
import 'react-native-gesture-handler';
import React from 'react';
import { StatusBar } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Home from './Home';
import Tickets from './Tickets';
const Stack = createStackNavigator();
function App(): JSX.Element {
return (
<>
<StatusBar barStyle='dark-content' hidden />
<NavigationContainer>
<Stack.Navigator
initialRouteName='Home'
>
<Stack.Screen
name='Home'
options={{
headerShown: false,
}}
>
{props => <Home {...props} username='Bella' />}
</Stack.Screen>
<Stack.Screen
name='Tickets'
component={Tickets}
options={{
headerTitleAlign: 'center',
headerTitleStyle: { fontFamily: 'Ubuntu-Regular' }
}}
/>
</Stack.Navigator>
</NavigationContainer>
</>
);
}
export default App;
I have checked the documentation to make sure I set it correctly and that I wasnt doing something blatantly wrong, and I cant find anything suggesting that I did.
What I expected was for my code to not have an error I guess? Or at least for the error to be something that tells me what to do in more detail so I can fix it. There is an image that shows on the emulator where it throws the error, but its literally where the error is thrown and not what caused it.
Seen Here
I have seen people mention the below, but I seem to have this covered to my knowledge:
useNavigation only works if your component is inside of a NavigationContainer and a Navigator
I have also looked at this page, as multiple SO answers have suggested. I dont truly understand it, but from a surface level I dont think it applies if I AM navigating with navigation prop:
Link Here
I cant just get rid of the component, thats not a viable option. So I'm hoping someone here has some advice.
Stumbled into an answer. Not sure if it is THE answer but it worked. Detailed below:
In my Menu file, I had this:
onPress={navigation.navigate('Tickets')}
But I suppose what it wanted, or what ended up working at least was:
onPress={navigation.navigate(Tickets)}
Notice the lack of single quotes.
What I did was import the Tickets component to the Menu file and used that for the Navigate call.
UPDATE TO ADD METHOD #2
It's been a few days, but I found another answer. In my App file, you can see I named the components with single quotes. Changing them to double quotes fixed this as well, for me at least.
Example:
<Stack.Screen
name='Tickets' // CHANGE THIS TO name="Tickets"
component={Tickets}
options={{
headerTitleAlign: 'center',
headerTitleStyle: { fontFamily: 'Ubuntu-Regular' }
}}
/>
I am using Expo for my app. I have a horizontal Flatlist where I render my data react native paper's Card. I saw Card have onPress function. I used that to navigate the another page. But onPress function does not trigger on Android device. I know React native's touchable-opacity have positioning issue on Android. I tried hitSlop and inline styling zIndex but still does not work. I also wrap my card with react-native's touchable-opacity and play with positioning still did not help me, only it works when i used react-native-gesture-handler's touchable-opacity but then it does not work on IOS. Hope anyone can help me...
import React from 'react';
import { Card } from 'react-native-paper';
import { useNavigation } from '#react-navigation/native';
interface Iprops {
item: string;
}
export default function RenderCard({ item }: Iprops) {
const navigation = useNavigation();
return (
<Card
hitSlop={{ "bottom": 30, "top": 30, "right": 30, "left": 30 }}
onPress={() => {
navigation.navigate(`detail`, { // THIS DOES NOT TRIGGER ON ANDROID
"id": `${item.pk}`
});
}}
style={{ "marginBottom": 20 }}>
<Card.Cover
source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" />
</Card.Actions>
</Card>
);
}
I've noticed that using onPressIn or onPressOut does work on Android within an absolute positioned flatlist, but onPress does not work. I hope this might be of help to someone out there looking for an answer.
You'll need to use the TouchableOpacity element from react-native-gesture-handler.
Like you told, you should add touchable opacity to the element you are rendering on the card. TouchableOpacity can be tricky. So, first give it a styling of borderWidth:1 and borderColor to see the actual touchable area on the screen. Then you start to bring them together with the icon or the image or whatever you are rendering. TouchableOpacity works but the positioning can be tricky. You have to understand it to use it better. Think touchableOpacity as a view with borders then it'll be easier to grasp. Also, if you dont give touchableOpacity an absolute position in the styling it will be out of the screen somewhere, I was never be able to bring it to somewhere that I can see to position it. So you can add 'position' as well.
I gave up on positioning and render my component's based on Platform.
Platform.OS === `ios` ?
<Card
onPress={() => {
navigation.navigate(`detail`, {
"id": `${item.pk}`
});
}}
style={{ "marginBottom": 20 }}>
<Card.Cover source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" right={Beer} />
</Card.Actions>
</Card> :
<TouchableOpacity
onPress={() => {
navigation.navigate(`detail`, {
"id": `${item.pk}`
});
}}
>
<Card style={{ "marginBottom": 20 }}>
<Card.Cover source={{ "uri": `${item.img_url}` }} />
<Card.Actions>
<Card.Title title={item.name} subtitle="Card Subtitle" right={Beer} />
</Card.Actions>
</Card>
</TouchableOpacity>;
Sorry in advance if this is a silly question but I'm going in circles here. I'm pretty new to react and node, and looking to connect my react native front end with my node back end. Pretty much every tutorial I read is telling me to "paste the fetch api code after the class declaration and before the render method", but I don't have a class declaration or render method in any of my code, so I'm a little confused about where to put the fetch api code? I don't know if this makes a huge difference but each screen of my app is in it's own file as it's own function and I am using a stack navigator to get between the screens with it's functionality contained in another file for the stack navigator.
If anyone could offer me some help I would really appreciate it, I am beyond confused about what to do.
Included below is my Login Screen function so you can see what I mean when I say the screens are set up as functions. All other screens are laid out the same way. Please let me know if you need to see anything else and I will edit and add it in!
import React from 'react';
function LoginScreen() {
return(
<View style={{ alignItems: "center", marginTop: 24 }}>
<Text style={styles.text}>
Login Screen
</Text>
</View>
);
}
export default LoginScreen
Again, I would appreciate any help anyone could give me as this is driving me demented and I would really like to get this working!
With functional components, you declare your "methods" inside your function:
function LoginScreen() {
const submit = () => {
//do something
}
return <View>
<Button title="Submit" onPress={submit} />
</View>
}
So, You are trying to use Functional Components instead of Class Based Component.
In Functional Components to send FetchAPI Request we use React Hooks, useEffect to send api request, and save the return data of API Request in another hook useState.
Please read more about React Hooks here,
https://reactjs.org/docs/hooks-intro.html
In your above scenario fetch api request with functional components will be something like this,
import React, {useEffect, useState} from 'react';
function LoginScreen() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('yourapi.com/user')
.then(res => res.json())
.then(data => setData(data));
}, []);
return(
<View style={{ alignItems: "center", marginTop: 24 }}>
<Text style={styles.text}>
// You Can Use Your Data Here {data}
Login Screen
</Text>
</View>
);
}
export default LoginScreen
A most pro and less verbose way to do it is using axios library. Check this code out:
import React, { useState, useEffect } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
export default function LoginScreen() {
const [user, setUser] = useState({});
const termToSearchFor = 'edilsonlm217';
useEffect(() => {
async function loadAPI() {
const response = await axios.get(`https://api.github.com/users/${termToSearchFor}`);
setUser(response.data);
}
loadAPI();
}, []);
return (
<View style={{ alignItems: "center", marginTop: 24 }}>
<Text>
{user.bio}
</Text>
</View>
);
}
This piece of code searchs for my user "edilsonlm217" in the public github's API right away after the component load. It gets the response from response.data and set it to user state then print my bio on screen.
Don't forget to install axios as dependecy to your project before use it.
I would like to ask you about section selected on pictures below.
What is the name of this section and how I can style it in React Native? At now my APK have an ugly white bar and I can't see level of battery or WiFi.
The area with the battery and time is called the status bar. In most cases I've seen, the status bar is given a set height depending on the platform from ReactNative's Platform module.
Afterwards, you can pass this height to a <View> and add additional styling.
import { Platform, ... } from 'react-native'
...code...
const STATUS_BAR_HEIGHT = Platform.select({ ios: 20, android: 24 })
export default class MyComponent extends Component {
...code...
render() {
<View style={{ height: STATUS_BAR_HEIGHT, ...more styles here... }} />
<View>
...code...
</View>
}
}
I want all screens on my app to appear below the status bar on both iOS and Android, so I'd either have to add a StatusBar component or a paddingTop to all my screens.
Is there a way to do this globally? Where is the appropriate top level component to add the StatusBar in a Redux app? (e.g. which part of https://github.com/react-community/react-navigation/tree/master/examples/ReduxExample)?
Step 1: Import Platform and StatusBar
import { Platform, StatusBar} from 'react-native';
Step 2: Add this style in parent View
paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0
Full Code:
import React, { Component } from 'react';
import {
Text, View,
Platform, StatusBar
} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={{ paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0 }}>
<Text>This is Text</Text>
</View>
);
}
}
You can create a <NavigationContainer/> component to hold all your different pages, so that you don't need to duplicate the StatusBar and padding code in every single screen component.
I created a example in here: https://snack.expo.io/SyaCeMOwW
And nothing need to change in term of your navigation structure or redux flow.