Pied de page fixe React Native

128

J'essaie de créer une application native de réaction qui ressemble à une application Web existante. J'ai un pied de page fixe en bas de la fenêtre. Quelqu'un a-t-il une idée de la façon dont cela peut être réalisé avec react native?

dans l'application existante, c'est simple:

.footer {
  position: fixed;
  bottom: 0;
}
4ega
la source

Réponses:

167

Du haut de ma tête, vous pouvez le faire avec un ScrollView . Votre conteneur de niveau supérieur peut être un conteneur flexible, à l'intérieur qui a un ScrollView en haut et votre pied de page en bas. Ensuite, dans le ScrollView, placez simplement le reste de votre application comme d'habitude.

Colin Ramsay
la source
fonctionne très bien =) thx, vient d'être ajouté heightà la vue du pied de page et ça a l'air bien sur 4s et 6
4ega
1
Cela marche. Mais je ne pouvais pas comprendre pourquoi. Pourquoi ça marche?
Aditi
171

Voici le code réel basé sur la réponse Ramsay de Colin:

<View style={{flex: 1}}>
  <ScrollView>main</ScrollView>
  <View><Text>footer</Text></View>
</View>
Alexandre Zaytsev
la source
1
Oui je l'ai essayé mais sans flex n'a pas fonctionné: D Merci d'avoir poussé pour essayer à nouveau :) Et si vous avez cliqué sur l'entrée, je veux mentionner d'utiliser onContentSizeChange. Alors ce que j'ai fait, j'ai fait défiler la vue en haut comme ceci: onContentSizeChange = {(width, height) => this.refs.scrollView.scrollTo ({y: this.state.onInputSelectScrollViewPaddingSize})}
Ernestyno
1
ça ne marche pas. Je ne vois pas pourquoi cela fonctionnerait dans tous les cas
Paulo Roberto Rosa
63

J'utilise des pieds de page fixes pour les boutons de mon application. La façon dont j'implémente un pied de page fixe est la suivante:

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

Et si vous avez besoin que le pied de page se déplace vers le haut lorsqu'un clavier apparaît par exemple, vous pouvez utiliser:

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

Ensuite, utilisez {bottom: this.state.btnLocation} dans votre classe de pied de page fixe. J'espère que ça aide!

dahveed707
la source
2
Quiconque obtient 'undefined n'est pas un objet (évaluant "DeviceEventEmitter.addListener")' en essayant de faire 'this.setState (...)' sur les écouteurs du clavier?
John Sardinha
@JohnSardinha Essayez à la import { Keyboard} from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)place.
maxhungry
23

Vous obtenez d'abord la dimension, puis vous la manipulez via le style flex

var Dimensions = require('Dimensions')
var {width, height} = Dimensions.get('window')

En rendu

<View style={{flex: 1}}>
    <View style={{width: width, height: height - 200}}>main</View>
    <View style={{width: width, height: 200}}>footer</View>
</View>

L'autre méthode consiste à utiliser flex

<View style={{flex: 1}}>
    <View style={{flex: .8}}>main</View>
    <View style={{flex: .2}}>footer</View>
</View>
Syarul
la source
17

@Alexander Merci pour la solution

Ci-dessous le code exactement ce que vous recherchez

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

Ci-dessous la capture d'écran

ScrollView avec pied de page fixe

Ashok R
la source
Bel exemple :)
joey rohan
7

Vous voudrez peut-être également jeter un œil à NativeBase ( http://nativebase.io ). Il s'agit d'une bibliothèque de composants pour React Native qui incluent une belle structure de mise en page ( http://nativebase.io/docs/v2.0.0/components#anatomy ), y compris des en-têtes et des pieds de page.

C'est un peu comme Bootstrap pour Mobile.

Simon Ordish
la source
1
Il n'inclut pas la mise en page du pied de page fixe.
svlada
7

Des trucs simples ici:

Dans le cas où vous n'avez pas besoin d'un ScrollView pour cette approche, vous pouvez utiliser le code ci-dessous pour obtenir quelque chose comme ceci:

Quelque chose comme ça

<View style={{flex: 1, backgroundColor:'grey'}}>
    <View style={{flex: 1, backgroundColor: 'red'}} />
    <View style={{height: 100, backgroundColor: 'green'}} />
</View>
Cherag Verma
la source
7

Vous trouverez ci-dessous le code pour définir le pied de page et les éléments ci-dessus.

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,
  },
});
shruti garg
la source
6

La façon dont je l'ai fait était d'avoir une vue (appelons-la P) avec flex 1, puis à l'intérieur de cette vue ont 2 vues supplémentaires (C1 et C2) avec flex 0.9 et 0.1 respectivement (vous pouvez changer les hauteurs de flex aux valeurs requises) . Ensuite, à l'intérieur du C1 ont une vue de défilement. Cela a parfaitement fonctionné pour moi. Exemple ci-dessous.

<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>
Rajesh
la source
En plus de cela, les styles gauche, droit et inférieur de valeur 0 doivent être fournis pour que cela fonctionne.
IVI
5

On pourrait réaliser quelque chose de similaire en réagissant natif avec position: absolute

let footerStyle = {
  position: 'absolute',
  bottom: 0,
}

Il y a cependant quelques points à garder à l'esprit.

  1. absolute positionne l'élément par rapport à son parent.
  2. Vous devrez peut-être définir manuellement la largeur et la hauteur de l'élément.
  3. La largeur et la hauteur changeront lorsque l'orientation change. Cela doit être géré manuellement

Une définition de style pratique ressemblerait à ceci:

import { Dimensions } from 'react-native';

var screenWidth = Dimensions.get('window').width; //full screen width

let footerStyle = {
  position: 'absolute',
  bottom: 0,
  width: screenWidth,
  height: 60
}
Akash Kurian Jose
la source
5

J'ai trouvé que l'utilisation de flex était la solution la plus simple.

<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>
saiftyfirst
la source
4

Lorsque flex est un nombre positif, cela rend le composant flexible et sa taille sera proportionnelle à sa valeur flex. Ainsi, un composant avec flex défini sur 2 prendra deux fois plus d'espace qu'un composant avec flex défini sur 1.

   <View style={{flex: 1}>
            
     <ScrollView>
        //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>

iambinodstha
la source
1
Pensez à ajouter quelques explications à votre réponse.
HMD
3

Le meilleur moyen est d'utiliser la propriété justifyContent

<View style={{flexDirection:'column',justifyContent:'flex-end'}}>
     <View>
        <Text>fixed footer</Text>
    </View>
</View>

si vous avez plusieurs éléments d'affichage à l'écran, vous pouvez utiliser

<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>
Manzoor Samad
la source
3
import {Dimensions} from 'react-native'

const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;

puis sur l'écriture de ces styles

 position: 'absolute',
 top: HEIGHT-80,
 left: 0,
 right: 0,

a fonctionné comme un charme

Joseph Owigo
la source
2

Pour les problèmes Android avec ceci:

dans app / src / AndroidManifest.xml, remplacez windowSoftInputMode par ce qui suit.

<activity
   android:windowSoftInputMode="stateAlwaysHidden|adjustPan">

Je n'ai eu absolument aucun problème avec cela dans iOS en utilisant react-native et keyboardAwareScroll. J'étais sur le point d'implémenter une tonne de code pour comprendre cela jusqu'à ce que quelqu'un me donne cette solution. A parfaitement fonctionné.

Lisa Faye Cook
la source
2

si vous utilisez simplement react native pour pouvoir utiliser le code suivant

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

également, vous pouvez utiliser https://docs.nativebase.io/ dans votre projet natif react, puis faire quelque chose comme ce qui suit

<Container>

{/*Your Main Content*/}
<Content>

<ScrollView>
   {/* Your List View ,etc */}
</ScrollView>

</Content>

{/*Your Footer*/}
<Footer>
   {/*Elements*/}
</Footer>

</Container>

React_Native

NativeBase.io

ab_did96
la source
2

Définissez android: windowSoftInputMode = "AdjustPan" dans votre fichier manifeste, et cela fonctionnera comme vous le souhaitez.

Andresh Singh
la source
1

Je pense que le meilleur et le plus facile serait comme ci-dessous, placez simplement le reste de votre vue dans un contenu et un pied de page dans une vue séparée.

`<Container>
   <Content>
     <View>
      Ur contents
    </View>
  </Content>
  <View>
  Footer
  </View>
</Container>`

ou vous pouvez utiliser le pied de page de la base native

`<Container>
  <Content>
    <View>
Ur contents
    </View>
  </Content>
<Footer>
Footer
</Footer>
</Container>`
Aishwarya Shetty
la source
1

Suggestion 1

=> Corps avec pied de page fixe

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

Image de démonstration

Modifier 2

=> Corps et pied de page fixe avec onglets

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

entrez la description de l'image ici

Remarques

import {TouchableOpacity} in 'react-native'

Avantages

Nous pouvons utiliser ce simple pied de page sans réagir à la navigation du bas

DevAelius
la source