4ega
4ega

Reputation: 2122

React Native fixed footer

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

Answers (23)

Muhammad Umar
Muhammad Umar

Reputation: 229

Easy way to fix footer at the bottom:

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

Leandro Ariel
Leandro Ariel

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

Alessander Franca
Alessander Franca

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

iambinodstha
iambinodstha

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

Hardik Desai
Hardik Desai

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>

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

Upvotes: 5

Cao YongFeng
Cao YongFeng

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

dahveed707
dahveed707

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

Joseph Owigo
Joseph Owigo

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

shruti garg
shruti garg

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

Aishwarya Shetty
Aishwarya Shetty

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

Andresh Singh
Andresh Singh

Reputation: 124

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

Upvotes: 1

Ryan Didevar
Ryan Didevar

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>

React_Native

NativeBase.io

Upvotes: 2

Lisa Faye Cook
Lisa Faye Cook

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

saiftyfirst
saiftyfirst

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

Akash
Akash

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.

  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
}

Upvotes: 5

Cherag Verma
Cherag Verma

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 :

Something like this

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

Upvotes: 10

Alexander Zaytsev
Alexander Zaytsev

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

Manzoor Samad
Manzoor Samad

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

Rajesh
Rajesh

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

Simon Ordish
Simon Ordish

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

Colin Ramsay
Colin Ramsay

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

Ashok R
Ashok R

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

ScrollView With Fixed Footer

Upvotes: 17

syarul
syarul

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

Related Questions