Reputation: 2122
I'm trying to create a react native app that looks like an existing web app. I have a fixed footer at bottom of the window. Does anyone have an idea how this can be achieved with react native?
In the existing app it's simple:
.footer {
position: fixed;
bottom: 0;
}
Upvotes: 188
Views: 344418
Reputation: 229
import { StyleSheet, Text, View } from 'react-native'
import React from 'react'
const Footer = () => {
return (
<View style={styles.footer}>
<Text style={{ color: 'black', fontSize: 15 }}>All rights reserved, 2022</Text>
</View>
)
}
const styles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
backgroundColor: '#F4CE14',
padding: 10,
justifyContent: 'center',
alignItems: 'center',
},
})
export default Footer;
Upvotes: 1
Reputation: 1381
Create a Style like this:
const styles = StyleSheet.create({
header:{ backgroundColor: "#00BFFF", height: "20%" },
footer:{ backgroundColor: "royalblue", height: "10%", flexDirection: "row", alignItems: "center" }
});
Then use the style in a tag :
<View style={styles.footer}>
<View style={{ flex: 1, alignItems: "center" }}>
<Pressable onPress={() => openCamera(true)}>
<View style={{ flexDirection: "column", alignItems: "center" }}>
<Icon name="camera" style={{ fontSize: 21, color: "white" }}/>
<Text style={{ color: "white" }}>Photo</Text>
</View>
</Pressable>
</View>
</View>
Upvotes: 0
Reputation: 2753
I've used a combination of height: 100%
and flex: 1
.
<View style={{ height: "100%" }}>
<View
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
height: 50,
}}
>
{R.map(
tab => (
<TouchableOpacity
key={tab.id}
onPress={() => setCurrentTab(tab)}
>
<Text>{tab.name}</Text>
</TouchableOpacity>
),
tabs
)}
</View>
<View style={{ flex: 1 }}>
<View style={{ height: "100%" }}>
<View style={{ flex: 1 }}>
<ScrollView
style={{
width: "100%",
}}
>
... ScrollView content
</ScrollView>
</View>
<View
style={{
borderTopColor: "#dadada",
borderTopWidth: 1,
width: "100%",
alignItems: "center",
justifyContent: "center",
height: 60,
paddingBottom: 10,
}}
>
<TouchableOpacity
style={{
padding: 8,
borderRadius: 3,
}}
>
<Text>
Show Results
</Text>
</TouchableOpacity>
</View>
</View>
</View>
Upvotes: 1
Reputation: 1007
When flex is a positive number, it makes the component flexible and it will be sized proportional to its flex value. So a component with flex set to 2 will take twice the space as a component with flex set to 1.
<View style={{flex: 1}>
<ScrollView style={{flex: 1}>
//your scroll able content will be placed above your fixed footer content.
//when your content will grow bigger and bigger it will hide behind
//footer content.
</ScrollView>
<View style={styles.footerContainer}>
//your fixed footer content will sit fixed below your screen
</View>
</View>
Upvotes: 7
Reputation: 1217
Suggestion 1
=> Body with fixed footer
<View style={{ flex: 1, backgroundColor: 'gray' }}>
<View style={{ flex: 9, backgroundColor: 'gray',alignItems: 'center', justifyContent: 'center', }}>
<Text style={{color:'white'}}>...Header or Body</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
<Text>...Footer</Text>
</View>
</View>
Edit 2
=> Body & Fixed footer with tabs
<View style={{ flex: 1, backgroundColor: 'gray' }}>
<View style={{ flex: 9, backgroundColor: 'gray', alignItems: 'center', justifyContent: 'center', }}>
<Text style={{ color: 'white' }}>...Header or Body</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center', }}>
<View style={{ flex: 1, flexDirection: 'row' }}>
<TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
<View>
<Text>
...Home
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
<View>
<Text>
...Settings
</Text>
</View>
</TouchableOpacity>
</View>
</View>
</View>
Notes
import {TouchableOpacity} from 'react-native'
Advantages
We can use this simple footer without react bottom navigation
Upvotes: 5
Reputation: 91
i created a package. it may meet your needs.
https://github.com/caoyongfeng0214/rn-overlaye
<View style={{paddingBottom:100}}>
<View> ...... </View>
<Overlay style={{left:0, right:0, bottom:0}}>
<View><Text>Footer</Text></View>
</Overlay>
</View>
Upvotes: 0
Reputation: 924
I'm using fixed footers for buttons in my app. The way I implement a fixed footer is like so:
<View style={{flex: 1}}>
<View><Text>my text</Text></View>
<View style={{position: 'absolute', left: 0, right: 0, bottom: 0}}><Text>My fixed footer</Text></View>
</View>
And if need the footer to move up when a keyboard appears for instance you can use:
const { DeviceEventEmitter } = React
class MyClass {
constructor() {
this.state = {
btnLocation: 0
}
}
componentWillMount() {
DeviceEventEmitter.addListener('keyboardWillShow', this.keyboardWillShow.bind(this))
DeviceEventEmitter.addListener('keyboardWillHide', this.keyboardWillHide.bind(this))
}
keyboardWillShow(e) {
this.setState({btnLocation: e.endCoordinates.height})
}
keyboardWillHide(e) {
this.setState({btnLocation: 0})
}
}
Then use {bottom: this.state.btnLocation} in your fixed footer class. I hope this helps!
Upvotes: 83
Reputation: 574
import {Dimensions} from 'react-native'
const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;
then on the write this styles
position: 'absolute',
top: HEIGHT-80,
left: 0,
right: 0,
worked like a charm
Upvotes: 5
Reputation: 332
Below is code to set footer and elements above.
import React, { Component } from 'react';
import { StyleSheet, View, Text, ScrollView } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.containerMain}>
<ScrollView>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
<Text> Main Content Here</Text>
</ScrollView>
<View style={styles.bottomView}>
<Text style={styles.textStyle}>Bottom View</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
containerMain: {
flex: 1,
alignItems: 'center',
},
bottomView: {
width: '100%',
height: 50,
backgroundColor: '#EE5407',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
bottom: 0,
},
textStyle: {
color: '#fff',
fontSize: 18,
},
});
Upvotes: 6
Reputation: 19
I think best and easy one would be as below, just place rest of ur view in a content and footer in a separate view.
`<Container>
<Content>
<View>
Ur contents
</View>
</Content>
<View>
Footer
</View>
</Container>`
or u can use footer from native-base
`<Container>
<Content>
<View>
Ur contents
</View>
</Content>
<Footer>
Footer
</Footer>
</Container>`
Upvotes: 0
Reputation: 124
Set android:windowSoftInputMode="adjustPan" in your manifest file, and it will work as you expect.
Upvotes: 1
Reputation: 678
if you just use react native so you can use the following code
<View style={{flex:1}}>
{/* Your Main Content*/}
<View style={{flex:3}}>
<ScrollView>
{/* Your List View ,etc */}
</ScrollView>
</View>
{/* Your Footer */}
<View style={{flex:1}}>
{/*Elements*/}
</View>
</View>
also, you can use https://docs.nativebase.io/ in your react native project and then do something like the following
<Container>
{/*Your Main Content*/}
<Content>
<ScrollView>
{/* Your List View ,etc */}
</ScrollView>
</Content>
{/*Your Footer*/}
<Footer>
{/*Elements*/}
</Footer>
</Container>
Upvotes: 2
Reputation: 121
For Android problems with this:
in app/src/AndroidManifest.xml change windowSoftInputMode to the following.
<activity
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
I had absolutely no problems with this in ios using react-native and keyboardAwareScroll. I was about to implement a ton of code to figure this out until someone gave me this solution. Worked perfectly.
Upvotes: 1
Reputation: 111
I found using flex to be the simplest solution.
<View style={{flex:1,
justifyContent: 'space-around',
alignItems: 'center',
flexDirection: 'row',}}>
<View style={{flex:8}}>
//Main Activity
</View>
<View style={{flex:1}}>
//Footer
</View>
</View>
Upvotes: 4
Reputation: 14027
One could achieve something similar in react native with position: absolute
let footerStyle = {
position: 'absolute',
bottom: 0,
}
There are a few things to keep in mind though.
absolute
positions the element relative to its parent.A practical style definition would look something like this:
import { Dimensions } from 'react-native';
var screenWidth = Dimensions.get('window').width; //full screen width
let footerStyle = {
position: 'absolute',
bottom: 0,
width: screenWidth,
height: 60
}
Upvotes: 5
Reputation: 299
Simple stuff here:
Incase you don't need a ScrollView for this approach you can go with the below code to achieve Something like this :
<View style={{flex: 1, backgroundColor:'grey'}}>
<View style={{flex: 1, backgroundColor: 'red'}} />
<View style={{height: 100, backgroundColor: 'green'}} />
</View>
Upvotes: 10
Reputation: 2884
Here's the actual code based on Colin's Ramsay answer:
<View style={{flex: 1}}>
<ScrollView>main</ScrollView>
<View><Text>footer</Text></View>
</View>
Upvotes: 258
Reputation: 929
The best way is to use justifyContent property
<View style={{flexDirection:'column',justifyContent:'flex-end'}}>
<View>
<Text>fixed footer</Text>
</View>
</View>
if you have multiple view elements on screen, then you can use
<View style={{flexDirection:'column',justifyContent:'space-between'}}>
<View>
<Text>view 1</Text>
</View>
<View>
<Text>view 2</Text>
</View>
<View>
<Text>fixed footer</Text>
</View>
</View>
Upvotes: 4
Reputation: 3778
The way I did this was to have a view (lets call it P) with flex 1, then inside that view have 2 more views (C1 and C2) with flex 0.9 and 0.1 respectively (you can change the flex heights to required values). Then, inside the C1 have a scrollview. This worked perfectly for me. Example below.
<View style={{flex: 1}}>
<View style={{flex: 0.9}}>
<ScrollView>
<Text style={{marginBottom: 500}}>scrollable section</Text>
</ScrollView>
</View>
<View style={{flex: 0.1}}>
<Text>fixed footer</Text>
</View>
</View>
Upvotes: 7
Reputation: 137
You might also want to take a look at NativeBase (http://nativebase.io). This a library of components for React Native that include some nice layout structure (http://nativebase.io/docs/v2.0.0/components#anatomy) including Headers and Footers.
It's a bit like Bootstrap for Mobile.
Upvotes: 7
Reputation: 16466
Off the top of my head you could do this with a ScrollView. Your top-level container could be a flex container, inside that have a ScrollView at the top and your footer at the bottom. Then inside the ScrollView just put the rest of your app as normal.
Upvotes: 236
Reputation: 20766
@Alexander Thanks for solution
Below is code exactly what you looking for
import React, {PropTypes,} from 'react';
import {View, Text, StyleSheet,TouchableHighlight,ScrollView,Image, Component, AppRegistry} from "react-native";
class mainview extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<View style={styles.mainviewStyle}>
<ContainerView/>
<View style={styles.footer}>
<TouchableHighlight style={styles.bottomButtons}>
<Text style={styles.footerText}>A</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.bottomButtons}>
<Text style={styles.footerText}>B</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
class ContainerView extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<ScrollView style = {styles.scrollViewStyle}>
<View>
<Text style={styles.textStyle}> Example for ScrollView and Fixed Footer</Text>
</View>
</ScrollView>
);
}
}
var styles = StyleSheet.create({
mainviewStyle: {
flex: 1,
flexDirection: 'column',
},
footer: {
position: 'absolute',
flex:0.1,
left: 0,
right: 0,
bottom: -10,
backgroundColor:'green',
flexDirection:'row',
height:80,
alignItems:'center',
},
bottomButtons: {
alignItems:'center',
justifyContent: 'center',
flex:1,
},
footerText: {
color:'white',
fontWeight:'bold',
alignItems:'center',
fontSize:18,
},
textStyle: {
alignSelf: 'center',
color: 'orange'
},
scrollViewStyle: {
borderWidth: 2,
borderColor: 'blue'
}
});
AppRegistry.registerComponent('TRYAPP', () => mainview) //Entry Point and Root Component of The App
Below is the Screenshot
Upvotes: 17
Reputation: 2189
You get the Dimension first and then manipulate it through flex style
var Dimensions = require('Dimensions')
var {width, height} = Dimensions.get('window')
In render
<View style={{flex: 1}}>
<View style={{width: width, height: height - 200}}>main</View>
<View style={{width: width, height: 200}}>footer</View>
</View>
The other method is to use flex
<View style={{flex: 1}}>
<View style={{flex: .8}}>main</View>
<View style={{flex: .2}}>footer</View>
</View>
Upvotes: 28