In react native, can we achieve a UI where there are multiple screens stacked on top of each other with each screen stacking on top of the other on click of a button.
Let's say, there is Screen A. Upon click of a button, Screen B is placed as a stack on Screen A and screen A is still partly visible as Screen B doesn't occupy the entire screen layout. Similarly, Screen C adds up to the stack upon the click of a button in Screen B and screen B is still visible along with screen A in the background. All these come with a side animation from the left (similar to navigation drawer). With a common button, all the above screens can be popped out from the stack and the previous screen comes to the top with a side animation again, this time to the right.
I wanted to understand if the above is possible in react native? If yes, how I can achieve it? I wish I can show the design but I cannot do that atm.
With react-native-vertical-view-pager you can do it.
install with:
npm install --save react-native-vertical-view-pager
or with yarn (if you use yarn):
yarn add react-native-vertical-view-pager
and use as follow:
import React from 'react';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
import VerticalViewPager from 'react-native-vertical-view-pager';
const { width, height } = Dimensions.get('window');
export default class App extends React.Component {
render() {
return (
<VerticalViewPager
showsVerticalScrollIndicator={false}>
<View style={[styles.page_container, {backgroundColor: 'pink'}]}>
<Text>Page1: Open up App.js to start working on your app!</Text>
</View>
<View style={[styles.page_container, {backgroundColor: 'olive'}]}>
<Text>Page2: Changes you make will automatically reload.</Text>
</View>
<View style={[styles.page_container, {backgroundColor: 'lightblue'}]}>
<Text>Page3: Shake your phone to open the developer menu.</Text>
</View>
</VerticalViewPager>
);
}
}
const styles = StyleSheet.create({
page_container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width,
height
}
});
with your screens on the place of the views.
I could achieve this functionality using a very cool library named 'react-native-modalfy'.
import React, { PureComponent } from 'react'
import {
Easing,
Dimensions,
StatusBar,
StyleSheet,
Text,
View,
} from 'react-native'
import { ModalProvider, createModalStack } from 'react-native-modalfy'
import CardModal from './modals/CardModal'
import Button from './components/Button'
const { width } = Dimensions.get('screen')
const config = { ModalA: CardModal, ModalB: CardModal, ModalC: CardModal }
const defaultOptions = {
transitionOptions: animatedValue => ({
opacity: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 1, .9],
}),
transform: [
{
perspective: 2000
},
{
translateX: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [-width / 2, 0, 25],
}),
},
{
scale: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [1.2, 1, .9],
}),
},
],
}),
animateInConfig: {
easing: Easing.bezier(.42,-0.03,.27,.95),
duration: 450,
},
animateOutConfig: {
easing: Easing.bezier(.42,-0.03,.27,.95),
duration: 450,
},
}
const stack = createModalStack(config, defaultOptions)
class App extends PureComponent {
render() {
return (
<ModalProvider stack={stack}>
<View style={styles.container}>
<StatusBar animated hidden translucent />
<Text style={styles.title}>RNM</Text>
<Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
<Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
<Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
</View>
</ModalProvider>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'indigo',
alignItems: 'center',
justifyContent: 'center'
},
title: {
color: 'white',
fontSize: 54,
fontWeight: 'bold',
marginBottom: 50,
},
})
export default App
import React, { PureComponent } from 'react'
import {
Button as ButtonModule,
Dimensions,
StyleSheet,
Text,
View,
} from 'react-native'
import Button from '../components/Button'
const { width: ww, height: wh } = Dimensions.get('screen')
class CardModal extends PureComponent {
componentDidMount() {
const { modal } = this.props
this.modalListenerID = modal.addListener('onAnimate', this._handleAnimation)
}
componentWillUnmount() {
this.modalListenerID?.remove()
}
_handleAnimation = animatedValue => {
const { currentModal } = this.props.modal
console.info(`${currentModal}:`, animatedValue)
}
render() {
const {
currentModal,
closeModal,
closeModals,
closeAllModals,
params: { color },
} = this.props.modal
return (
<View style={[styles.card]}>
<Text style={styles.title(color)}>{currentModal}</Text>
<Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
<Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
<Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
<ButtonModule title="Close" onPress={closeModal} color="dodgerblue" />
<ButtonModule title={`Close all ${currentModal}`} onPress={() => closeModals(currentModal)} color="dodgerblue" />
<ButtonModule title="Close all modals" onPress={closeAllModals} color="red" />
</View>
)
}
}
const styles = StyleSheet.create({
title: color => ({
color,
fontSize: 48,
fontWeight: 'bold',
marginBottom: 50,
}),
card: {
marginRight : 90,
width: ww,
height: wh,
backgroundColor: 'cyan',
elevation: 0,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 0,
},
})
export default CardModal
import React, { PureComponent } from 'react'
import { TouchableOpacity, StyleSheet, Text } from 'react-native'
import { withModal } from 'react-native-modalfy'
class Button extends PureComponent {
openModal = () => {
const { color, modalToOpen, modal } = this.props
modal.openModal(modalToOpen, { color })
}
render() {
const { color, label } = this.props
return (
<TouchableOpacity onPress={this.openModal} style={styles.button(color)}>
<Text style={styles.label}>{label}</Text>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
button: backgroundColor => ({
backgroundColor,
paddingHorizontal: 60,
paddingVertical: 21,
borderRadius: 21,
marginBottom: 30,
}),
label: {
fontSize: 16,
fontWeight: '800',
color: 'white',
textAlign: 'center',
},
})
export default withModal(Button)
Related
I am trying to change a class into a function. This is mainly because if I can get it working, I want to use it for learning different animations, I have had some success but not 100%. Originally it displayed an icon that when clicked it spun it one way and then when clicked again it spun the other way. What I have tried to do it get rid of the icon and replace it with an image. It works when clicked once but then does nothing.
I am struggling with toggled aspect of it and setting the state I think because I cant seem to set it up properly in a function.
I have tried several things but this is the best I can get. If I show the original code and then what I have managed to change, maybe someone can point me in the right direction as to what I am doing wrong.
All I want is the image to display and then when clicked spins right and then if clicked again it spins left.
I am doing this so I can mess around with the settings and hopefully learn animation a bit better.
Any help would be greatly appreciated.
The original code :
import React from 'react';
import { View, StyleSheet, Animated, Image, TouchableOpacity } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
const TabIcon = ({
onPress,
menuToggled
}) => {
const logoStyles = [styles.logoStyle];
if (menuToggled !== null) {
const animation = new Animated.Value(menuToggled ? 0 : 1);
Animated.timing(animation, {
toValue: menuToggled ? 1 : 0,
duration: 500,
useNativeDriver: true
}).start();
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
logoStyles.push(animatedStyles);
}
return (
<TouchableOpacity
style={styles.tabStyle}
onPress={onPress}
>
<Animated.View style={logoStyles}>
<Animated.Image
style={styles.tinyLogo}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/></Animated.View>
</TouchableOpacity>
);
};
export default class App extends React.Component {
state = {
menuToggled: null
}
toggleMenu = () => {
this.setState(prevState => {
return { menuToggled: !prevState.menuToggled };
});
}
render () {
return (
<View style={styles.container}>
<TabIcon
onPress={this.toggleMenu}
menuToggled={this.state.menuToggled}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
},
tinyLogo: {
width: 150,
height: 150,
borderRadius: 100,
margin: 8,
},
});
and what I have changed so far :
import React, { useRef, useState } from "react";
import { View, StyleSheet, Animated, Image, TouchableOpacity, Easing } from 'react-native';
import Constants from 'expo-constants';
const App = () => {
const spinValue = useRef(new Animated.Value(0)).current;
const [menuToggled, setMenuToggled] = useState([null]);
toggleMenu = () => {
setMenuToggled(menuToggled === "null" ? "menuToggled" : "null");
}
const Spinner = ({
onPress,
menuToggled
}) => {
const logoStyles = [styles.logoStyle];
const animation = new Animated.Value(0);
const go = () => {
Animated.timing(animation, {
toValue: 1,
duration: 1500,
easing: Easing.elastic(1),
useNativeDriver: true
}).start();
}
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
logoStyles.push(animatedStyles);
return (
<TouchableOpacity
onPress={go}
>
<Animated.View style={logoStyles}>
<Animated.Image
style={styles.tinyLogo}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/></Animated.View>
</TouchableOpacity>
);
};
return (
<View style={styles.container}>
<Spinner
onPress={toggleMenu}
menuToggled={menuToggled}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
},
tinyLogo: {
width: 150,
height: 150,
borderRadius: 100,
margin: 8,
},
});
export default App;
There are a few issues. You first had menuToggled initialized to [null] when it should have been null. You also had forgotten to use onPress in TabIcon. The most noteworthy thing was wrapping TabIcon in a useCallback to prevent it from being recreated all the time. Expo snack:
import React, { useRef, useState, useCallback } from 'react';
import {
View,
StyleSheet,
Animated,
Image,
TouchableOpacity,
} from 'react-native';
import Constants from 'expo-constants';
const App = () => {
const spinValue = useRef(new Animated.Value(0)).current;
const [menuToggled, setMenuToggled] = useState(null);
const TabIcon = useCallback(({ onPress, menuToggled }) => {
const logoStyles = [styles.logoStyle];
// initialized base on menuToggled
// if not done then it will take an additional button press to trigger
// the animation
const animation = useRef(new Animated.Value(menuToggled ? 0 : 1)).current;
const startAnimation = () => {
Animated.timing(animation, {
toValue: menuToggled ? 1 :0,
duration: 500,
useNativeDriver: true,
}).start();
};
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
logoStyles.push(animatedStyles);
return (
<TouchableOpacity
onPress={() => {
startAnimation();
onPress?.();
}}>
<Animated.View style={logoStyles}>
<Animated.Image
style={styles.tinyLogo}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/>
</Animated.View>
</TouchableOpacity>
);
},[]);
return (
<View style={styles.container}>
<TabIcon
onPress={() => setMenuToggled((prev) => !prev)}
menuToggled={menuToggled}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
},
tinyLogo: {
width: 150,
height: 150,
borderRadius: 100,
margin: 8,
},
});
export default App;
I am trying to learn FlatList component of react-native. Observing a tutorial, I have implemented a sample applications which list components inside a scrollview. I am trying to replace scrollview with FlatList, but items are not renderings on the screen. I have included the main source code here.
App.js
import React, { Component } from 'react'
import {
StyleSheet,
View,
ScrollView,
FlatList
} from 'react-native'
import ColorButton from './components/ColorButton'
class App extends Component {
constructor() {
super()
this.state = {
backgroundColor: 'blue'
}
this.changeColor = this.changeColor.bind(this)
}
changeColor(backgroundColor) {
this.setState({backgroundColor})
}
render() {
const { backgroundColor } = this.state
return(
<FlatList
data = {'red', 'green', 'salmon'}
renderItem = {(color) => {
<ColorButton backgroundColor={color} onSelect={this.changeColor}></ColorButton>
} } />
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20
}
})
export default App
ColorButton.js
import React from 'react'
import {
StyleSheet,
Text,
View,
TouchableHighlight
} from 'react-native'
const ColorButton = ({ backgroundColor, onSelect=f=>f }) => (
<TouchableHighlight
style = {styles.button}
onPress={() => onSelect(backgroundColor)}
underlayColor="orange">
<View style = {styles.row}>
<View style = {[styles.sample, {backgroundColor}]} />
<Text style = {styles.text}>backgroundColor</Text>
</View>
</TouchableHighlight>
)
const styles = StyleSheet.create({
button: {
margin: 10,
padding: 10,
borderWidth: 2,
borderRadius: 10,
alignSelf: 'stretch',
backgroundColor: 'rgba(255,255,255,0.8)'
},
row: {
flexDirection: 'row',
alignItems: 'center'
},
sample: {
height: 20,
width: 20,
borderRadius: 10,
margin: 5,
backgroundColor: 'white'
},
text: {
fontSize: 30,
margin: 5
}
})
export default ColorButton
Change your code for flatlist to the one below :
<FlatList
data = {['red', 'green', 'salmon']}
renderItem = {({item}) => {
<ColorButton backgroundColor={item} onSelect={this.changeColor}>
</ColorButton>
} } />
Hope it helps. feel free for doubts
I am developing a sample app as part of learning react-native, in which it has a ColorForm that accepts the value from a TextInput and with the help of Props, the data will be sent to the Main view, such as App. The App has a SectionList that doesn't update with the new value inputs from ColorForm.
Following is the source code that I have used:
App.js
import React, { Component } from 'react'
import {
StyleSheet,
SectionList,
Text,
Alert
} from 'react-native'
import ColorButton from './components/ColorButton'
import ColorForm from './components/ColorForm'
class App extends Component {
constructor() {
super()
this.state = {
backgroundColor: 'blue',
availableColors: ['red', 'green', 'yellow', 'pink']
}
this.changeColor = this.changeColor.bind(this)
this.newColor = this.newColor.bind(this)
}
changeColor(backgroundColor) {
this.setState({ backgroundColor })
}
newColor(color) {
const colors = [
...this.state.availableColors,
color
]
this.setState(colors)
}
render() {
const { backgroundColor, availableColors } = this.state
return (
<SectionList style={styles.list}
backgroundColor={backgroundColor}
sections={[{ title: "Header", data: availableColors }]}
renderSectionHeader={({ section }) => (
<ColorForm onNewColor={this.newColor} />
)}
renderItem={({ item }) => (
<ColorButton backgroundColor={item} onSelect={this.changeColor} />
)}
keyExtractor={(item, index) => index}
/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20
},
list: {
marginTop: 40
}
})
export default App
ColorForm.js
import React, { Component } from 'react'
import {
View,
Text,
StyleSheet,
TextInput
} from 'react-native'
import PropTypes from 'prop-types'
export default class ColorForm extends Component {
constructor() {
super()
this.state = {
txtColor: ''
}
this.submit = this.submit.bind(this)
}
submit() {
this.props.onNewColor(this.state.txtColor.toLowerCase())
this.setState({ txtColor: '' })
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.txtInput}
placeholder="Enter a color..."
onChangeText={(txtColor) => this.setState({ txtColor })}
value={this.state.txtColor}
/>
<Text style={styles.button} onPress={this.submit}>Add</Text>
</View>
)
}
}
ColorForm.propTypes = {
onNewColor: PropTypes.func.isRequired
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'lightgrey',
height: 70,
paddingTop: 20
},
txtInput: {
flex: 1,
margin: 5,
padding: 5,
borderWidth: 2,
fontSize: 20,
borderRadius: 5,
backgroundColor: 'snow'
},
button: {
backgroundColor: 'darkblue',
margin: 5,
padding: 5,
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: 20
}
})
Can anyone help me to sort out the issue? Thanks in advance.
It looks like the state is not being updated in your method newColor, since availableColors is an array u can use push operation to add new value to the array update the code as below and it will work.
newColor(color) {
console.log('adding', color)
const colors = this.state.availableColors
colors.push(color)
this.setState(colors)
}
Currently I have this code:
import React, { Component, PureComponent } from 'react';
import { View, FlatList, RefreshControl, StatusBar, Animated, ScrollView, PanResponder } from 'react-native';
import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen';
import { connect } from 'react-redux';
import i18n from 'i18n-js';
import Post from '../components/Post';
import AppHeader from '../components/AppHeader';
class Posts extends PureComponent {
constructor(props) {
super(props);
this.state = {
curY: new Animated.Value(0),
height: 0
};
}
render() {
const { postsReducer } = this.props,
{ container } = styles;
return (
<View style={container}>
<Animated.View
style={{
transform: [{
translateY: this.state.curY.interpolate({
inputRange: [0, 1],
outputRange: [0, -1]
})
}], position: 'absolute', top: 0, width: wp('100%'), marginTop: StatusBar.currentHeight
}}
onLayout={({ nativeEvent }) => this.setState({ height: nativeEvent.layout.height })}
>
<AppHeader />
</Animated.View>
<Animated.ScrollView
scrollEventThrottle={16}
refreshControl={
<RefreshControl
onRefresh={this._onRefresh}
refreshing={refreshing}
tintColor='#5E81F4'
colors={["blue", "lightblue"]}
/>
}
contentContainerStyle={{ marginTop: this.state.height }}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.curY } } }],
{ useNativeDriver: true }
)}
>
{postsReducer.map((item, index) => (
<Post
postId={item._id}
userId={item.owner}
owner={item.owner}
title={item.title}
avatar={item.picture}
userName={item.userName}
updatedAt={item.updatedAt}
image={item.photo.split(",")}
description={item.description}
age={item.age}
time={item.time}
date={item.date}
location={item.location}
city={item.city}
commentCounter={item.commentCounter}
key={index}
/>
))}
</Animated.ScrollView>
</View>
);
}
}
const styles = {
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
}
};
const mapStateToProps = ({ registrationReducer, postsReducer, usersReducer, }) => (
{
registrationReducer,
postsReducer,
usersReducer
}
);
export default connect(mapStateToProps, { setPosts })(Posts);
When I start scrolling down header hides, and when I scroll up again appears. But header appears only when I get to the beginning of list.
And I need such solution: when I'm for example in the middle of the list and start scroll up - header should appear, and when started scroll down it hides again. So it should be independently from position.
It work this way in Facebook mobile app for example.
I found solution. Just need to use Animated.diffClamp.
Here is the final code. Maybe will be useful for someone:
import React, { Component, PureComponent } from 'react';
import { View, FlatList, RefreshControl, StatusBar, Animated, ScrollView, PanResponder } from 'react-native';
import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen';
import { connect } from 'react-redux';
import i18n from 'i18n-js';
import Post from '../components/Post';
import AppHeader from '../components/AppHeader';
class Posts extends PureComponent {
constructor(props) {
super(props);
this.state = {
curY: new Animated.Value(0),
height: 0
};
}
render() {
const { postsReducer } = this.props,
{ container } = styles;
const headerDistance = Animated.diffClamp(this.state.curY, 0, 60).interpolate({
inputRange: [0, 1],
outputRange: [0, -1]
});
return (
<View style={container}>
<Animated.ScrollView
scrollEventThrottle={16}
refreshControl={
<RefreshControl
onRefresh={this._onRefresh}
refreshing={refreshing}
tintColor='#5E81F4'
colors={["blue", "lightblue"]}
/>
}
contentContainerStyle={{ marginTop: this.state.height }}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.curY } } }],
{ useNativeDriver: true }
)}
>
{postsReducer.map((item, index) => (
<Post
postId={item._id}
userId={item.owner}
owner={item.owner}
title={item.title}
avatar={item.picture}
userName={item.userName}
updatedAt={item.updatedAt}
image={item.photo.split(",")}
description={item.description}
age={item.age}
time={item.time}
date={item.date}
location={item.location}
city={item.city}
commentCounter={item.commentCounter}
key={index}
/>
))}
</Animated.ScrollView>
<Animated.View
style={{
transform: [{
translateY: headerDistance
}], position: 'absolute', top: 0, width: wp('100%'), marginTop: StatusBar.currentHeight
}}
onLayout={({ nativeEvent }) => this.setState({ height: nativeEvent.layout.height })}
>
<AppHeader />
</Animated.View>
</View>
);
}
}
const styles = {
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
}
};
const mapStateToProps = ({ registrationReducer, postsReducer, usersReducer, }) => (
{
registrationReducer,
postsReducer,
usersReducer
}
);
export default connect(mapStateToProps, { setPosts })(Posts);
I have tried to implement the component expand to full screen in react native by using Layout animation in react-native but it was not good to look. Can any one help me in getting it?
changeLayout = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({ expanded: !this.state.expanded });
};
I expect to expand the component on click to full screen and again collapse it on click.
Set the initial value you want through the animation, obtain the screen width and height, and create a click function to execute.
This is an example that I made. Click this link if you want to run it yourself.
import React from 'react';
import { Animated, Text, View,Dimensions,Button } from 'react-native';
const screenwidth = Dimensions.get('screen').width
const screenheight = Dimensions.get('screen').height
class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(50),
fadeAnim2: new Animated.Value(50),
}
componentDidMount() {
}
animatebutton() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: screenheight,
duration: 10000, // Make it take a while
}
).start();
Animated.timing( // Animate over time
this.state.fadeAnim2, // The animated value to drive
{
toValue: screenwidth,
duration: 10000, // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim,fadeAnim2 } = this.state;
return (
<Animated.View // Special animatable View
style={{
...this.props.style,
height: fadeAnim,
width : fadeAnim2
}}
>
{this.props.children}
</Animated.View>
);
}
}
// You can then use your `FadeInView` in place of a `View` in your components:
export default class App extends React.Component {
constructor(props){
super(props);
this.state={
}
}
animatebutton(){
this.fade.animatebutton();
}
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}} >
<FadeInView style={{backgroundColor: 'powderblue'}} ref={ani => this.fade = ani}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
<Button title="go animate" onPress={() => this.animatebutton()}/>
</View>
)
}
}
OR
You can use LayoutAnimation that you want to use. Look at my example.
import React, {Component} from "react";
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
LayoutAnimation,
} from 'react-native';
class App extends Component {
constructor() {
super();
this.state = {
check: false,
}
}
onPresscheck() {
// Uncomment to animate the next state change.
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
// Or use a Custom Layout Animation
// LayoutAnimation.configureNext(CustomLayoutAnimation);
this.setState({ check : !this.state.check});
}
render() {
var middleStyle = this.state.check === false ? {width: 20,height:20} : {width: "100%",height:"100%"};
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={() => this.onPresscheck()}>
<Text>pressbutton</Text>
</TouchableOpacity>
<View style={[middleStyle, {backgroundColor: 'seagreen'}]}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button: {
width:"100%",
height: 60,
backgroundColor: 'blue',
alignItems: 'center',
justifyContent: 'center',
margin: 8,
},
});
export default App;
Please refer to this blog :
https://dev-yakuza.github.io/en/react-native/react-native-animatable/
Also, try using this library. Use any animation type you want and render them.
Happy coding :)