React Native create a FoldView using react-native-foldview module

React React Native Android Ios application Apk IPA Foldview

React-Navigation provides a 100% feel native application fold view in android and ios both. Today we are going to learn how to create a fold view in my react-native application. 

Project Folder Structure

android
ios
node_modules
src
    Componets
      AdditionalInfoCard.js
      InfoCard.js
      Lines.js
      PhotoCard.js
      ProfileCard.js
      ProfileDetailCard.js
    App.js
    Row.js
app.json
babel.config.js
index.js
metro.config.js
package-lock.json
package.json

 

  • Creating New Project run this command
     react-native init <Project-name>

 

  • After then create a project add node package
     npm install --save react-native-foldview

 

  • After then Open  index.js  under the Project folder and add this code.
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

 

  • After then src folder under the project folder like "project-name/src/" and cut the App.js of the root folder and paste src folder
  • After that add this code in App.js
import React from 'react';
import {
Platform,
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
View,
} from 'react-native';
import Row from './Row';
const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : 0;
const styles = StyleSheet.create({
   container: {
     flex: 1,
  },
  scrollView: {
    backgroundColor: '#4A637D',
    flex: 1,
   padding: 10,
   paddingTop: STATUSBAR_HEIGHT,
  },
});

export default () => (
<SafeAreaView style={styles.container}>
   <StatusBar
     barStyle="dark-content"/>
   <ScrollView
     style={styles.scrollView}>
     <Row zIndex={100} />
     <Row zIndex={90} />
     <Row zIndex={80} />
     <Row zIndex={70} />
   </ScrollView>
</SafeAreaView>
);

 

  • After That Create Row.js in the src folder and add the code
import React, {
Component,
} from 'react';

import {
LayoutAnimation,
UIManager,
View,
} from 'react-native';

import FoldView from 'react-native-foldview';
import InfoCard from './components/InfoCard';
import PhotoCard from './components/PhotoCard';
import ProfileCard from './components/ProfileCard';

// Enable LayoutAnimation on Android
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
const ROW_HEIGHT = 180;
const Spacer = ({ height }) => (
<View
pointerEvents="none"
style={{
height,
}}
/>
);
export default class Row extends Component {
constructor(props) {
super(props);
this.state = {
expanded: false,
height: ROW_HEIGHT,
};
}

componentWillMount() {
this.flip = this.flip.bind(this);
this.handleAnimationStart = this.handleAnimationStart.bind(this);
this.renderFrontface = this.renderFrontface.bind(this);
this.renderBackface = this.renderBackface.bind(this);
}
flip() {
this.setState({
expanded: !this.state.expanded,
});
}
handleAnimationStart(duration, height) {
const isExpanding = this.state.expanded;
const animationConfig = {
duration,
update: {
type: isExpanding ? LayoutAnimation.Types.easeOut : LayoutAnimation.Types.easeIn,
property: LayoutAnimation.Properties.height,
},
};

LayoutAnimation.configureNext(animationConfig);
this.setState({
height,
});
}

renderFrontface() {
return (
<InfoCard onPress={this.flip} />
);
}

renderBackface() {
return (
<ProfileCard onPress={this.flip} />
);
}
render() {
const { height } = this.state;
const { zIndex } = this.props;
const spacerHeight = height - ROW_HEIGHT;
return (
  <View
     style={{
     flex: 1,
     zIndex,
    }}
  >
  <View
     style={{
     height: ROW_HEIGHT,
     margin: 10,
    }} 
  >
  <FoldView
    expanded={this.state.expanded}
    onAnimationStart={this.handleAnimationStart}
    perspective={1000}
    renderBackface={this.renderBackface}
    renderFrontface={this.renderFrontface}
  >
   <PhotoCard onPress={this.flip} />
  </FoldView>
 </View>
 <Spacer height={spacerHeight} />
</View>
);
}
}

 

  • After then create the components folder under the src folder and create an AdditionalInfoCard.js, InfoCard.js, Lines.js, PhotoCard.js, ProfileCard.js, and ProfileDetailCard.js file then add code
AdditionalInfoCard.js

import React from 'react';
import {
View,
StyleSheet,
} from 'react-native';
import {
ThinGrayLine,
ThickDarkGrayLine,
} from './Lines';
export default ({ onPress }) => (
<View
style={{
flex: 1,
paddingTop: 10,
paddingHorizontal: 16,
flexDirection: 'row',
backgroundColor: '#FFFFFF',
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: '#BDC2C9',
}}
>
<View style={{ flex: 1 }}>
   <ThickDarkGrayLine width={100} />
   <ThinGrayLine width={80} onPress={onPress} />
</View>

<View style={{ flex: 1 }}>
   <ThickDarkGrayLine width={60} />
   <ThinGrayLine width={120} />
</View>
</View>
);

InfoCard.js
import React from 'react';
import {
View,
StyleSheet,
} from 'react-native';

import {
ThinGrayLine,
ThickGrayLine,
ThickDarkGrayLine,
ThinRedLine,
} from './Lines';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
flexDirection: 'row',
},
leftPane: {
flex: 1,
backgroundColor: '#33373B',
padding: 16,
flexDirection: 'column',
justifyContent: 'space-between',
},
rightPane: {
flex: 2,
padding: 16,
backgroundColor: '#fff',
},
});
export default ({ onPress }) => (
<View style={styles.container}>
<View style={styles.leftPane}>
  <ThickGrayLine />
<View>
  <ThinRedLine onPress={onPress} />
  <ThickGrayLine width={80} />
</View>
</View>
<View style={styles.rightPane}>
  <View style={{ flex: 1, flexDirection: 'column' }}>
    <ThickGrayLine width={140} />
    <ThickGrayLine width={160} />
  </View>
  <View style={{ flexDirection: 'row' }}> 
    <View style={{ flex: 1 }}>
    <ThinGrayLine width={60} />
    <ThickDarkGrayLine width={60} />
  </View>
  <View style={{ flex: 1 }}>
   <ThinGrayLine width={60} />
   <ThickDarkGrayLine width={60} />
  </View>
 </View>
 </View>
</View>
);

Lines.js

import React from 'react';
import {
View,
TouchableHighlight,
} from 'react-native';
const Line = ({ style, onPress }) => {
if (onPress) {
return (
<TouchableHighlight
style={[
{
marginBottom: 10,
borderRadius: 2,
},
style,
]}
onPress={onPress}
>
<View />
</TouchableHighlight>
);
}
return (
<View
style={[
{
marginBottom: 10,
},
style,
]}
/>
);
};
const ThinLine = ({ color, width = 60, ...props }) => (
<Line
style={{
width,
backgroundColor: color,
height: 10,
}}
{...props}
/>
);
const ThickLine = ({ color, width = 70, ...props }) => (
<Line
style={{
width,
backgroundColor: color,
height: 20,
}}
{...props}
/>
);

export const ThinGrayLine = (props) => (
<ThinLine color={'#BDC2C9'} {...props} />
);

export const ThickGrayLine = (props) => (
<ThickLine color={'#BDC2C9'} {...props} />
);

export const ThickWhiteLine = (props) => (
<ThickLine color={'#FFFFFF'} {...props} />
);

export const ThickDarkGrayLine = (props) => (
<ThickLine color={'#33373B'} {...props} />
);

export const ThinRedLine = (props) => (
<ThinLine color={'#DB0000'} {...props} />
);

PhotoCard.js

import React from 'react';
import {
View,
StyleSheet,
} from 'react-native';
import {
ThinGrayLine,
ThickWhiteLine,
} from './Lines';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#33373B',
padding: 10,
flexDirection: 'column',
},
card: {
flex: 1,
backgroundColor: '#FFFFFF',
justifyContent: 'flex-end',
},
});

export default ({ onPress }) => (
<View style={styles.container}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: '#5A4A9C',
height: 40,
padding: 10,
}}
>
   <ThickWhiteLine width={40} onPress={onPress} />
   <ThickWhiteLine width={60} onPress={onPress} />
   <ThickWhiteLine width={40} onPress={onPress} />
</View>
<View style={styles.card}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
paddingBottom: 0,
}}
onPress={onPress}
>
   <ThinGrayLine width={40} onPress={onPress}/>
   <ThinGrayLine width={80} onPress={onPress} />
   <ThinGrayLine width={50} onPress={onPress} />
</View>
</View>
</View>
);

ProfileCard.js

import React, {
Component,
} from 'react';
import {
View,
Text,
TouchableHighlight,
StyleSheet,
} from 'react-native';
import FoldView from 'react-native-foldview';
import ProfileDetailCard from './ProfileDetailCard';
import AdditionalInfoCard from './AdditionalInfoCard';
import {
ThinGrayLine,
ThickDarkGrayLine,
} from './Lines';
export default class ProfileCard extends Component {

componentWillMount() {
this.renderBackface = this.renderBackface.bind(this);
this.renderInnerBackFace = this.renderInnerBackFace.bind(this);
}
renderBlankFace() {
return (
<View
style={{
backgroundColor: '#D6EFFF',
flex: 1,
}}
/>
);
}
renderBackface() {
const onPress = this.props.onPress;
return (
<View style={{ flex: 1 }}>
<FoldView
renderFrontface={this.renderBlankFace}
renderBackface={this.renderInnerBackFace}
>
<AdditionalInfoCard onPress={onPress} />
</FoldView>
</View>
);
}
renderInnerBackFace() {
const onPress = this.props.onPress;
return (
<View
style={{
backgroundColor: '#fff',
flex: 1,
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: '#BDC2C9',
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
}}
>
<View
style={{
backgroundColor: '#FFBD18',
flex: 1,
margin: 14,
borderRadius: 2,
}}
>
<TouchableHighlight
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}
onPress={onPress}
>
<Text>
PRESS ME
</Text>
</TouchableHighlight>
</View>
</View>
);
}
render() {
const onPress = this.props.onPress;
return (
<View
style={{
flex: 1,
backgroundColor: '#fff',
flexDirection: 'column',
}}
>
<View style={{ flex: 1 }} >
<View
style={{
flex: 1,
paddingBottom: 10,
padding: 16,
}}
>
<ThinGrayLine width={120} />
<View
style={{
marginTop: 10,
flexDirection: 'row',
}}
>
<TouchableHighlight
onPress={onPress}
>
<View
style={{
width: 40,
height: 40,
marginRight: 10,
backgroundColor: '#BDC2C9',
}}
/>
</TouchableHighlight>
<View
style={{
   flex: 1,
   flexDirection: 'column',
}}
>
  <ThickDarkGrayLine width={200} />
  <ThinGrayLine width={120} />
</View>
</View>
</View>
<View style={{ flex: 1 }}>
  <FoldView
    renderFrontface={this.renderBlankFace}
    renderBackface={this.renderBackface} 
  >
   <ProfileDetailCard onPress={onPress} />
  </FoldView>
</View>
</View>
</View>
);
}
}

ProfileDetailCard.js

import React from 'react';
import {
View,
StyleSheet,
} from 'react-native';
import {
ThinGrayLine,
ThickGrayLine,
} from './Lines';

const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 10,
paddingHorizontal: 16,
flexDirection: 'row',
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: '#BDC2C9',
},
});
export default ({ onPress }) => (
<View style={styles.container}>
<View style={{ flex: 1 }}>
   <ThickGrayLine width={60} />
   <ThinGrayLine width={120} />
</View>
<View style={{ flex: 1 }}>
   <ThickGrayLine width={60} onPress={onPress} />
   <ThinGrayLine width={120} />
</View>
</View>
);

Fold View in React Native using React-Native-Foldview is done.

Run command

react-native run-android
react-native run-ios


if you change the App name then you delete the android and ios folder of your project. After that run this command

 npm i -s react-native-eject / yarn add react-native-eject
 react-native eject


this command help to create android and ios folder with clean status

Thank you

Github link: https://github.com/Sudarshan101/react-native-foldview
youtube: https://www.youtube.com/watch?v=MqcZ3ct-LQ0

About the author
Code solution

info@codesolution.co.in

Discussion
  • 0 comments

Add comment To Login
Add comment