How to hide status bar in Android w/ React Native? - react-native

How to hide status bar in Android w/ React Native?
https://facebook.github.io/react-native/docs/statusbarios.html#content

You no longer need to install a dependency to hide the status bar in react-native. The following should work for both Android and iOS.
To hide the StatusBar you can use the component straight from react-native. It is listed in the documentation here.
You can use it in two different ways. One as a component, and the other imperatively. For both you import it from react-native.
import { StatusBar } from 'react-native';
Component
In side your render:
render() {
return (
<View style={styles.container}>
<StatusBar hidden={true} /> // <- you could set this from a value in state
...
</View>
);
}
Imperatively
This allows you to hide it via a function call.
componentDidMount () {
// doesn't have to be in the componentDidMount it could be in some other function call.
StatusBar.isHidden(true);
}

<StatusBar backgroundColor={'transparent'} translucent={true} />
:D

You can try react-native-android-statusbar
.
var StatusBarAndroid = require('react-native-android-statusbar');
StatusBarAndroid.hideStatusBar()

Related

How would you do that opening effect with React Native?

Imagine a feed of items and then you click on one item and it opens in this way. We need to create a news app that has this identical animation (check sec 00:13 of video linked). enter link description here
You can use the react-native-collapsible package to achieve something like this
https://github.com/oblador/react-native-collapsible
One way to do this is to do dynamic styling.
like this:
import React from "react";
import { View, TouchableOpacity} from "react-native";
const Component = () => {
const [isOpen, setisOpen] = React.useState(false);
return (
<TouchableOpacity onPress={() => setisOpen(!isOpen)}>
<View>
{/* The View content that is always open */}
</View>
<View style={isOpen ? { disply: "flex" } : { disply: "none" }}>
{/* The View content to be opened/hidden */}
</View>
</TouchableOpacity>
);
};
then you can just import this component in your screen like this:
<Component />
Depend on the navigation library you are using but I will assume that you are using react-navigation.
You have this package to perform an animation with shared element during navigation between two screens: https://github.com/IjzerenHein/react-navigation-shared-element.
Very easy to use and very performant.

navigation does not work when imported - React native

When I use props.navigation.navigate("example"), it works normally. But if I import the component on another page it doesn't work anymore, props returns an empty object.
Works Fine:
const Menu = props =>{
console.log(props)
return(
<View style={styles.menuStyle}>
<TouchableOpacity style={styles.topicDiv} onPress={() =>props.navigation.navigate("Ads")}>
<View>
<Image style={styles.topicStyle} source={require ("../assets/security-camera.png")}/>
<Text style={styles.textStyle}>Câmeras</Text>
<Text style={styles.subTextStyle}>Veja como está a praia ao vivo 📷</Text>
If i try import Menu, navigation does not work:
import React from "react";
import { View } from "react-native";
import Menu from "./menu";
const Supermenu = () =>{
return(
<View>
<Menu></Menu>
</View>
)
}
export default Supermenu
If you use <Menu> inside of another component like <Supermenu>, React Navigation has no way to pass its navigation property in there. It only happens automatically if a component is a direct child of a screen (or its component property).
To have navigation available in Menu regardless of its position in the hierarchy, as long as it's a child of <NavigationContainer>, the best way is to make use of the useNavigation hook:
import { useNavigation } from '#react-navigation/core';
const Menu = props =>{
const navigation = useNavigation();
return (
<View style={styles.menuStyle}>
<TouchableOpacity style={styles.topicDiv} onPress={() => navigation.navigate("Ads")}>
...
See documentation for more detail.
If you are on an older version, there was also a HOC withNavigation that you could use.
You could also do the same in Supermenu and then pass navigation down manually.
use import {userNavigation} from '#react-navigation/core' instead of props navigate or you can add navigation props to the Menu component.

ReactNative Cannot update a component from inside the function body of a > different component

My HomeHeader component is like this:
import React from "react";
import { View, StyleSheet, Text, Image } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome5";
export default function HomeHeader({ navigation }) {
return (
<View style={styles.home_header}>
<Icon
style={styles.menu}
name="bars"
size={30}
color="white"
onPress={navigation.toggleDrawer()}
/>
<Image
style={styles.header_logo}
source={require("../assets/logo.png")}
/>
<Text>Hello</Text>
</View>
);
}
And am using it in my Home screen like this:
return (
<View>
<HomeHeader navigation={navigation} />
</View>
)
But am receiving this error message:
Warning: Cannot update a component from inside the function body of a
different component.
What am trying to do is, I have separated out the header section of my HOME screen into a separate component called HomeHeader. And in this component, am attaching the event handler to toggle the opening/closing of the DrawerNavigation (left side drawer menu)
If I create a Button in my HOME screen and add the event handler to toggle the drawer, it works fine. But the issue happens only if I try this from inside my HomeHeader component.
Btw, am using ReactNavigation v5 and I even tried this method: https://reactnavigation.org/docs/connecting-navigation-prop/
No luck so far.
Change onPress={ navigation.toggleDrawer() } to onPress={ ()=> navigation.toggleDrawer() }
You can read more about this in here

React Native Web - Control the html tag generated by View?

I have a react native web project. At one point, I would like my View instead of generating a <div> to generate a <label> element.
Is there a way to control this? I am hoping for some sort of htmlTag attribute that gets ignored if this is not compiling for a browser environment.
There was a component prop but it's removed in favor of accessibilityRole (Remove component prop).
You can use accessibilityRole to specify the label tag and even create a custom element using it:
function Label({ text }) {
return <View accessibilityRole="label">{text}</View>
}
and then use it like this:
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View>
<Label text="Test input:"/>
<TextInput name="test-input"/>
</View>
</View>
);
}
}
Check this working Expo snack: https://snack.expo.io/#clytras/change-rn-web-div-tag
How about making your own wrapper of View? It could check what environment it is running in, and then if it's in a browser then you can return the label element instead.
You could also use the accessibilityLabel prop on the TextInput, which will add an aria-label prop to the React Native code when it compiles to html for web.
In terms of accessibility, this accomplishes the same effect as a label attribute. See the React Native web docs on accessibility: https://necolas.github.io/react-native-web/docs/accessibility/
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View>
<TextInput accessibilityLabel="test-input" name="test-input"/>
</View>
</View>
);
}
}

How to hide the statusBar when react-native modal shown?

I want to hide the status bar, when modal window is shown.
My setup is as following, but it won't work as expected:
<StatusBar animated={true} hidden={true} translucent={true}>
Use statusBarTranslucent
If your status bar is translucent, you can set statusBarTranslucent to the modal.
Added since React Native 0.62
<Modal {...props} statusBarTranslucent>...</Modal>
Credit: https://github.com/react-native-modal/react-native-modal/issues/50#issuecomment-607535322
This is a known issue and there seems to be no official/React way to fix it yet. You can follow the discussion here:
https://github.com/facebook/react-native/issues/7474
I saw a post in this discussion which proposes a hack to hide it, but I haven't tried it on my project. You can also upvote this trick if it works for you.
<View style={styles.outerContainer}
<View style={styles.container}>
<StatusBar hidden={true}/>
<View style={styles.content}>
</View>
<Modal animation={fade} transparent={true}>
{/*Modal Contents Here*/}
</Modal>
</View>
A more solid fix may be changing the theme of activity in native android code.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
<!-- Customize your theme here. -->
</style>
<style name="AppTheme.Launcher">
<item name="android:windowBackground">#drawable/launch_screen</item>
</style>
</resources>
Credits go to Traviskn and mbashiq who proposed fixes above. I recommend you to subscribe that issue.
According to the documentations, you should be able to hide status bar in both iOS and Android using this
import {StatusBar} from 'react-native';
StatusBar.setHidden(true);
We can use the background of StatusBar to solve this problem easily but may not the best.
<Modal transparent>
{Platform.OS === 'android' ?
<StatusBar backgroundColor="rgba(0,0,0,0.5)"/>
: null
}
<View style={{backgroundColor: 'rgba(0,0,0,0.5)'}}>
// ModalContent here
</View>
</Modal>
Just use the same background and this problem can be solved.
I am actually facing the same issue for some time, I tried many solutions but I didn't get rid of this problem. I also tried to use native Android code to hide the StatusBar for a single component it works in other component but when I use it in modal it just not working. So, at last, I got a solution that works for me. I remove the modal view and replace it with react-navigation to navigate to a specific path and handle the back button using BackHandler component.
i achieve this creating a custom status bar component with a modal prop:
import React from 'react'
import { StatusBar } from 'react-native'
const MyStatusBar = (props) => {
const { backgroundColor } = props
const { barStyle } = props
const { translucent } = props
const { hidden } = props
const { showHideTransition } = props
const { modal } = props;
(modal !== undefined) ? StatusBar.setHidden(true) : StatusBar.setHidden(false)
return (
<StatusBar showHideTransition={showHideTransition} hidden={hidden} translucent={translucent} backgroundColor={backgroundColor} barStyle={barStyle} />
)
}
export default MyStatusBar
inside my base component modal prop is undefined so custom status bar is shown:
<MyStatusBar backgroundColor={theme.colors.primary} barStyle={'light-content'} />
and then calling inside the component who call the modal:
<MyStatusBar modal={modalVisible ? true : undefined} />
I think the root of my problem is the same, but it appeared a little different than how it is described above.
Expected behaviour: When the Modal becomes visible the StatusBar should hide.
const [showModal, setShowModal] = useState(false)
...
<Modal
visible={showModal}
>
<StatusBar hidden={showModal} />
...
Actual bahviour: Sometimes the StatusBardissapears as expected, other times just the StatusBar background color goes away and the actual StatusBar remains.
Workaround: Due to the flickering behaviour I think the problem is a racing condition of the native Android dialog. Therefore, I built a custom Modal component that uses the StatusBar imperative api to make sure the StatusBar hide call is made before the Modal appears. So far the Problem has not reappeared.
Here is the custom Modal component:
const Modal = ({ visible, children, ...rest }) => {
const [modalVisibility, setModalVisibility] = useState(false);
useEffect(() => {
if (visible) {
StatusBar.setHidden(true);
setModalVisibility(true);
} else {
StatusBar.setHidden(false);
setModalVisibility(false);
}
}, [visible]);
return (
<RNModal
visible={modalVisibility}
{...rest}
>
{children}
</RNModal>
);
};
export default Modal;
Hello you can try this
<View style={styles.outerContainer}
<View style={styles.container}>
<StatusBar hidden={true}/>
<View style={styles.content}>
</View>
<Modal animation={fade} transparent={true}>
{/* Contents Here*/}
</Modal>
</View>
<StatusBar backgroundColor={'transparent'} translucent={true} />