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

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.


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>

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!


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>

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


Bel exemple :)
joey rohan


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>

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

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>

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
}

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>

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>


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>

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


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


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


2

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


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

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.