How would you do that opening effect with React Native? - 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.

Related

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.

Is there a property that makes Ionicons have some press feedback?

I'm using Ionicons from #expo/vector-icons in some parts of my application. I'm trying to ensure that all pressable elements in my UI have some sort of visual feedback. I checked the vector-icons API and didn't find any relevant properties but I just want to ensure I know the best way to achieve this.
My guess is that I would have to wrap all of the <Ionicons /> in a TouchableOpacity or another component of its type, other than TouchableWithoutFeedback. Is this correct? Is there a more direct way to achieve this? And is my suggestion the way to go?
I don't think code is relevant here, but here it is anyway:
import React from 'react'
import { StyleSheet } from 'react-native'
import { Ionicons } from '#expo/vector-icons'
import PropTypes from 'prop-types'
const HeaderIcon = (props) => {
return (
<Ionicons
style={styles.icon}
name={props.name}
color={props.color}
onPress={() => {
props.onPress()
}}
/>
)
}
You can wrap your icon component with TouchableHighlight
it has underlayColor property where you can pass color.
e.g
<TouchableHighlight onPress={onPress} underlayColor="red">
<View style={styles.button}>
<Text>Touch Here</Text>
</View>
</TouchableHighlight>
and also have two other underlay callbacks such as onShowUnderlay and onHideUnderlay these callbacks can be used in different scenarios
Like onShowUnderlay you can change icon color or trigger any other function.

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: Not smooth scrolling with DrawerNavigator

Current Behavior
My code:
class App extends Component {
render() {
return <Drawer /> {/* rigid scrolling effect */}
return <Stack /> {/* smooth scrolling effect if I comment above return statement */}
}
}
const Drawer = DrawerNavigator({
Feed: { screen: Feed }
})
const Stack = StackNavigator({
Feed: { screen: Feed }
})
And Feed component's render is just a bunch of lines:
render() {
return <View style={{flex:1}}>
<ScrollView>
<Text>random line...</Text>
// .. more lines to make it scrollable
</ScrollView>
</View>
}
Expected Behavior
The expected behavior is to get smooth scrolling effect in both cases. However, DrawerNavigator screen's scrolling effect is extremely rigid. When I swipe my finger quickly from up to down, it doesn't keep scrolling smoothly automatically like it should in Stacknavigator example.
How to reproduce
Create App.js file above and create a simple Feed.js component which has a bunch of lines to make ScrollView work.
Can anybody help?
Update: Live demonstration: https://snack.expo.io/Hk8Np7nPG
Try this
render() {
return (
<View style={{flex:1}}>
<ScrollView>
<View>
{Your Contnet}
</View>
</ScrollView>
</View>
)}
it is worked for me...
hope it'll also worked for you
You can Use NativeBase with standard tabs Container and Contet (like ScrollView ) Header and...
first try :
npm install native-base --save
then:
npm i
react-native link
and here is your full example code:
import React, { Component } from 'react';
import { Content , View , Text } from 'native-base'; //don't need import 'react-native' components
export default class GeneralExample extends Component {
render() {
return (
<Content >
<View>
{Your Contnet}
</View>
</Content>
)}
}
and if you wanna change the speed just ScrollView try:
<ScrollView decelerationRate={0.5}>
<View/>
</ScrollView>
in NativeBase Use THIS LINK

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} />