Im learing React native but i dont understand how to get everything to not overlap with the status bar.
I have tried
translucent={true/flase}
hidden
This is expected behaviour, one solution is to add a padding to your top level view equal to current height of status bar or have a StatusBarView that has same height as the status bar.
Refer to this plugin https://github.com/jgkim/react-native-status-bar-size for listening to status bar height changes.
For e.g
import _ from 'lodash';
import React, { Component } from 'react';
import { View, StatusBar} from 'react-native';
import StatusBarSizeIOS from 'react-native-status-bar-size';
const STATUS_BAR_EXTRA_PADDING = 2;
const DEFAULT_STATUS_BAR_HEIGHT = 10;
class StatusBarView extends Component {
state = {
statusBarHeight: _.get(StatusBarSizeIOS, 'currentHeight', DEFAULT_STATUS_BAR_HEIGHT);
}
_handleStatusBarSizeDidChange = (statusBarHeight) => this.setState({ statusBarHeight })
componentDidMount() {
StatusBarSizeIOS.addEventListener('didChange', this._handleStatusBarSizeDidChange);
}
render() {
return (
<View
style={{
height: this.state.statusBarHeight + STATUS_BAR_EXTRA_PADDING,
}}
>
<StatusBar {...this.props} />
</View>
);
}
}
export default StatusBarView;
Now inside your screens you could do something like
import StatusBarView from '{view_path}';
...
render() {
return (
<View>
<StatusBarView barStyle="default" />
<View>{rest of the view}</View>
</View>
);
}
Related
I am working with Webview in React native.
Header and footer is not webview, and header includes navigation.goBack() button in it.
But it is not working even footer has navigation.navigate() button which is working.
Here is my code.
import 'react-native-gesture-handler';
import * as React from "react";
import { ImageBackground, StyleSheet, Text, View, Image, TextInput, TouchableOpacity } from "react-native";
import { AntDesign } from '#expo/vector-icons';
import { WebView } from 'react-native-webview';
import { height, width } from 'react-native-dimension';
import HeaderLink from './header_link';
import Footer from './footer';
const styles = StyleSheet.create({
container: {
flex: 1,
// flexDirection: "column"
},
});
class LinkPageScreen extends React.Component {
render() {
this.state = {
url: this.props.route.params.url,
title: this.props.route.params.title,
};
var linkURL = this.state.url;
return (
<View style={styles.container}>
<HeaderLink
image={false}
imageSource={{}}
left={
<TouchableOpacity onPress={ () => this.props.navigation.goBack(null) }>
....
</TouchableOpacity>
}
/>
<WebView
source={{uri: linkURL}}
style={{marginTop: height(12), marginBottom: height(11)}}
/>
<Footer navigation={this.props.navigation} />
</View>
)
}
}
export default LinkPageScreen
I changed navigation.goBack into navigation.navigate() but it was not working also in header.
I checked for same error on stackoverflow but webview.goback() function was there, and my problem is not like that. I am sure.
I found the solution. Even I don't know why.
I changed the code like below.
class LinkPageScreen extend React.component {
render() {
return (
<View>
<WebView .... />
<Header />
<Footer />
......
Unbelivably it works, i just changed the order of tags between webview and header.
Anyone can explain to me why this is happening?
Thanks.
You can try the code below:
import { useNavigation } from '#react-navigation/native';
const {goBack} = useNavigation();
const navigateBack = useCallback(() => {
goBack();
}, [goBack]);
.
.
.
<TouchableOpacity onPress={navigateBack}>
....
</TouchableOpacity>
So I have created a simple react-native following the Coursera lectures.
My Menu component just holds a list of recipes and displays them on the device.
import React, { Component } from 'react';
import { View, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
function Menu(props){
const renderMenuItem = ({item, index}) => {
return(
<ListItem
key={index}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
);
}
return(
<FlatList
data={props.dishes}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
)
}
export default Menu;
Next, there is the DishdetailComponent which renders the details of each dish.
import React from 'react';
import { Text, View } from 'react-native';
import { Card } from 'react-native-elements';
function RenderDish(props) {
const dish = props.dish;
if (dish != null) {
return(
<Card
featuredTitle={dish.name}
image={require('./images/uthappizza.png')}>
<Text style={{margin: 10}}>
{dish.description}
</Text>
</Card>
);
}
else {
return(<View></View>);
}
}
function Dishdetail(props) {
return(<RenderDish dish={props.dish} />);
}
export default Dishdetail;
And finally, I have the MainComponent which is like the top component holding the two previous components.
import { View } from 'react-native';
import { DISHES } from '../shared/dishes';
import Dishdetail from './DishdetailComponent';
class Main extends Component {
constructor(props){
super(props);
this.state = {
dishes: DISHES,
selectedDish: null
};
}
onDishSelect(dishId) {
this.setState({selectedDish: dishId})
}
render(){
return(
<View style={{flex:1}}>
<Menu dishes={this.state.dishes} onPress={(dishId) => this.onDishSelect(dishId)} />
<Dishdetail dish={this.state.dishes.filter((dish) => dish.id === this.state.selectedDish)[0]} />
</View>
);
}
}
export default Main;
When I run the app I get this
Did I miss something? Here is my repo if you want to have a closer look.
Few moments here:
1) Seems you forgot to import the Menu component at the top of imports
2) You simply have a typo in the import of DishdetailComponent
Just paste these lines instead of yours
import { View } from "react-native";
import { DISHES } from "../shared/dishes";
import Dishdetail from "./DishDetailComponent";
import Menu from "./MenuComponent";
Also, sometimes bunder crashes and don't reload.
To fix this I would suggest using
yarn start --reset-cache command (but don't forget to kill previous Metro Bundler instance) :)
While building a react-native application for Android I am getting the error
Cannot add a child that doesn't have Yoga Node to a parent without a
measure function
I tried with both remote debugger on and off but the problem persists.
Pasting my Component function as below.
import React, { Component } from 'react';
import { Text, TouchableWithoutFeedback, View } from 'react-native';
import { connect } from 'react-redux';
import { CardSection } from './common';
import * as actions from '../actions';
class ListItem extends Component {
render() {
const { title, id } = this.props.library;
const { titleStyle } = styles;
return (
<TouchableWithoutFeedback
onPress ={() => this.props.selectLibrary(id)}
>
<View> /* Using View as more then one card section is used */
<CardSection>
<Text style={titleStyle} >
{title}
</Text>
</CardSection>
</View>
</TouchableWithoutFeedback>
)
}
}
const styles = {
titleStyle: {
fontSize:18,
paddingLeft:10
}
};
export default connect(null, actions)(ListItem);
The problem is resolved once I moved my comments in front of the View tag to other location ( for example, before return statement)
I created a sort of demo on expo: https://snack.expo.io/#noitsnack/onpressin-twice
I tested this by scanning QR code in expo. This may be a expo bug.
I have wraped the expo symbol (an <Image>) in a <TouchableWithoutFeedback>. Here we see that when we press the expo symbol it causes the score to increase by one, and then the symbol moves to a new location. Sometimes it causes the onPressIn to trigger twice. I don't understand this, why does this happen?
Here is the code to the expo:
import React, { Component } from 'react';
import { Text, View, TouchableWithoutFeedback, Image, Dimensions } from 'react-native';
import IMAGE_EXPO from './assets/expo.symbol.white.png'
const IMAGE_SIZE = 100;
export default class App extends Component {
state = {
score: 0,
...getRandXY()
}
render() {
const { score, x, y } = this.state;
return (
<View style={{flex:1, backgroundColor:'steelblue' }}>
<Text style={{fontSize:72, textAlign:'center'}}>{score}</Text>
<TouchableWithoutFeedback onPressIn={this.addScore}>
<Image source={IMAGE_EXPO} style={{ width:IMAGE_SIZE, height:IMAGE_SIZE, left:x, top:y, position:'absolute' }} />
</TouchableWithoutFeedback>
</View>
)
}
addScore = e => {
this.setState(({ score }) => ({ score:score+1, ...getRandXY() }));
}
}
function getRandXY() {
return {
x: getRandInt(0, Dimensions.get('window').width - IMAGE_SIZE),
y: getRandInt(0, Dimensions.get('window').height - IMAGE_SIZE)
}
}
function getRandInt(min, max)
{
return Math.floor(Math.random()*(max-min+1)+min);
}
I'm using react navigation for my app development. When i run log-android, it keeps logging something like this.
Navigation Dispatch: Action: {...}, New State: {...}
which is from createNavigationContainer.js line 150.
I've run through github and document said it could be done by by setting onNavigationStateChange={null} on a top-level navigator.
How can i achieve this by setting onNavigationStateChange={null} and where should i set it?
I've try to set like below, but it the page will not be able to redirect to other page.
export default () => {
<App onNavigationStateChange={null} />
}
Below are my app.js code
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
import { StackNavigator,DrawerNavigator } from 'react-navigation';
import DrawerContent from './components/drawer/drawerContent.js';
import News from './components/news/home.js';
const drawNavigation = DrawerNavigator(
{
Home : {
screen : News ,
navigationOptions : {
header : null
}
}
},
{
contentComponent: props => <DrawerContent {...props} />
}
)
const StackNavigation = StackNavigator({
Home : { screen : drawNavigation,
navigationOptions: {
header: null
}
}
});
export default StackNavigation;
This is my drawerContent.js
import React, {Component} from 'react'
import {View,Text, StyleSheet,
TouchableNativeFeedback,
TouchableOpacity,
TouchableHighlight
} from 'react-native'
import { DrawerItems, DrawerView } from 'react-navigation';
import Icon from 'react-native-vector-icons/Octicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
class DrawerContent extends Component {
constructor(props){
super(props);
console.log('DrawerContent|testtttttt');
}
render(){
return (
<View style={styles.container}>
<Text>Hi darren</Text>
<TouchableOpacity style={{ marginBottom:5 }} onPress={() => this.props.navigation.navigate('RegistrationScreen') } >
<View style={styles.nonIconButton}>
<Text style={{ color: 'black',fontSize: 13 }} >Sign Up</Text>
</View>
</TouchableOpacity>
<Text>Hi darren</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default DrawerContent;
First, make sure you are using the latest release of react-navigation as the comment noting that the fix was committed is fairly recent.
Based on your code example, to disable logging for all navigation state changes, you would want to replace this code:
export default StackNavigation;
with:
export default () => (
<StackNavigation onNavigationStateChange={null} />
);
as StackNavigation appears to be your root navigator.
React navigation is great, but this logging is really bad. Solution
const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
render() {
return (
<AppNavigator onNavigationStateChange={null} />
);
}
}