React Native fixed footer

JavascriptReact Native

Javascript Problem Overview


I try to create react native app that looks like existing web app. I have a fixed footer at bottom of window. Do anyone have idea how this can be achieved with react native?

in existing app it's simple:

.footer {
  position: fixed;
  bottom: 0;
}

Javascript Solutions


Solution 1 - Javascript

Here's the actual code based on Colin's Ramsay answer:

<View style={{flex: 1}}>
  <ScrollView>main</ScrollView>
  <View><Text>footer</Text></View>
</View>

Solution 2 - Javascript

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.

Solution 3 - Javascript

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!

Solution 4 - Javascript

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>

Solution 5 - Javascript

@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

ScrollView With Fixed Footer

Solution 6 - Javascript

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 :

Something like this

<View style={{flex: 1, backgroundColor:'grey'}}>
    <View style={{flex: 1, backgroundColor: 'red'}} />
    <View style={{height: 100, backgroundColor: 'green'}} />
</View>

Solution 7 - Javascript

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.

Solution 8 - Javascript

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>

Solution 9 - Javascript

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,
  },
});

Solution 10 - Javascript

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.

  1. absolute positions the element relative to its parent.
  2. You might have to set the width and hight of the element manually.
  3. Width and hight will change when orientation changes. This has to be managed manually

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
}

Solution 11 - Javascript

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.

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

Solution 12 - Javascript

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>

Solution 13 - Javascript

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>

Solution 14 - Javascript

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

Solution 15 - Javascript

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>

Demo Image

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>

enter image description here

Notes

import {TouchableOpacity} from 'react-native'

Advantages

We can use this simple footer without react bottom navigation

Solution 16 - Javascript

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>

#React_Native #NativeBase.io

Solution 17 - Javascript

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.

Solution 18 - Javascript

Set android:windowSoftInputMode="adjustPan" in your manifest file, and it will work as you expect.

Solution 19 - Javascript

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>`

Solution 20 - Javascript

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>

Solution 21 - Javascript

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question4egaView Question on Stackoverflow
Solution 1 - JavascriptAlexander ZaytsevView Answer on Stackoverflow
Solution 2 - JavascriptColin RamsayView Answer on Stackoverflow
Solution 3 - Javascriptdahveed707View Answer on Stackoverflow
Solution 4 - JavascriptsyarulView Answer on Stackoverflow
Solution 5 - JavascriptAshok RView Answer on Stackoverflow
Solution 6 - JavascriptCherag VermaView Answer on Stackoverflow
Solution 7 - JavascriptSimon OrdishView Answer on Stackoverflow
Solution 8 - JavascriptRajeshView Answer on Stackoverflow
Solution 9 - Javascriptshruti gargView Answer on Stackoverflow
Solution 10 - JavascriptAkashView Answer on Stackoverflow
Solution 11 - JavascriptiambinodsthaView Answer on Stackoverflow
Solution 12 - JavascriptManzoor SamadView Answer on Stackoverflow
Solution 13 - JavascriptsaiftyfirstView Answer on Stackoverflow
Solution 14 - JavascriptJoseph OwigoView Answer on Stackoverflow
Solution 15 - JavascriptHardik DesaiView Answer on Stackoverflow
Solution 16 - JavascriptRyan DidevarView Answer on Stackoverflow
Solution 17 - JavascriptLisa Faye CookView Answer on Stackoverflow
Solution 18 - JavascriptAndresh SinghView Answer on Stackoverflow
Solution 19 - JavascriptAishwarya ShettyView Answer on Stackoverflow
Solution 20 - JavascriptCao YongFengView Answer on Stackoverflow
Solution 21 - JavascriptAlessander FrançaView Answer on Stackoverflow