Reaccionar pie de página fijo nativo


128

Intento crear una aplicación nativa de reacción que se parece a la aplicación web existente. Tengo un pie de página fijo en la parte inferior de la ventana. ¿Alguien tiene idea de cómo se puede lograr esto con reaccionar nativo?

en la aplicación existente es simple:

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

Respuestas:


167

Fuera de mi cabeza, podrías hacer esto con un ScrollView . Su contenedor de nivel superior podría ser un contenedor flexible, en el interior que tiene un ScrollView en la parte superior y su pie de página en la parte inferior. Luego, dentro de ScrollView, simplemente ponga el resto de su aplicación de manera normal.


funciona muy bien =) gracias, recién agregado heighta la vista de pie de página y se ve bien en 4s y 6
4ega

1
Esto funciona. Pero no pude entender por qué. ¿Por qué funciona esto?
Aditi

171

Aquí está el código real basado en la respuesta de Colin Ramsay:

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

1
Sí, lo intenté pero sin flexión no funcionó: D Gracias por presionar para intentarlo de nuevo :) Y si hizo clic en la entrada, quiero mencionar que use onContentSizeChange. Entonces, lo que hice desplacé la vista de desplazamiento superior de esta manera: onContentSizeChange = {(ancho, alto) => this.refs.scrollView.scrollTo ({y: this.state.onInputSelectScrollViewPaddingSize})}
Ernestyno

1
No funciona. No puedo ver por qué funcionaría en cualquier caso
Paulo Roberto Rosa

63

Estoy usando pies de página fijos para botones en mi aplicación. La forma en que implemento un pie de página fijo es así:

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

Y si necesita que el pie de página se mueva hacia arriba cuando aparece un teclado, por ejemplo, puede usar:

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

Luego use {bottom: this.state.btnLocation} en su clase de pie de página fijo. ¡Espero que esto ayude!


2
¿Alguien que obtiene 'undefined no es un objeto (evaluando "DeviceEventEmitter.addListener")' cuando intenta hacer 'this.setState (...)' en los oyentes del teclado?
John Sardinha

@JohnSardinha Intenta en su import { Keyboard} from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)lugar.
maxhungry

23

Primero obtienes la Dimensión y luego la manipulas a través del estilo flexible

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

En render

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

El otro método es usar flex

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

17

@Alexander Gracias por la solución

A continuación se muestra el código exactamente lo que buscas

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

A continuación se muestra la captura de pantalla

ScrollView con pie de página fijo


Buen ejemplo :)
joey rohan


7

Cosas simples aquí:

En caso de que no necesite un ScrollView para este enfoque, puede ir con el siguiente código para lograr algo como esto:

Algo como esto

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

7

A continuación se muestra el código para establecer el pie de página y los elementos anteriores.

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 forma en que hice esto fue tener una vista (llamémosla P) con flex 1, luego dentro de esa vista tener 2 vistas más (C1 y C2) con flex 0.9 y 0.1 respectivamente (puede cambiar las alturas de flex a los valores requeridos) . Luego, dentro del C1 tiene una vista de desplazamiento. Esto funcionó perfectamente para mí. Ejemplo a continuación.

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

Además de esto, se deben proporcionar los estilos izquierdo, derecho e inferior del valor 0 para que funcione.
IVI

5

Se podría lograr algo similar en reaccionar nativo con position: absolute

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

Sin embargo, hay algunas cosas a tener en cuenta.

  1. absolute coloca el elemento en relación con su padre.
  2. Puede que tenga que establecer el ancho y la altura del elemento manualmente.
  3. El ancho y la altura cambiarán cuando cambie la orientación. Esto tiene que ser manejado manualmente

Una definición de estilo práctica se vería así:

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

Encontré que usar flex es la solución más 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

Cuando flex es un número positivo, hace que el componente sea flexible y tendrá un tamaño proporcional a su valor de flex. Por lo tanto, un componente con flex configurado en 2 ocupará el doble de espacio que un componente con flex configurado en 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
Considere agregar alguna explicación a su respuesta.
HMD

3

La mejor manera es usar la propiedad justifyContent

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

Si tiene múltiples elementos de visualización en la pantalla, puede usar

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

luego en el escribir estos estilos

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

trabajado como un encanto


2

Para problemas de Android con esto:

en app / src / AndroidManifest.xml cambie windowSoftInputMode a lo siguiente.

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

No tuve absolutamente ningún problema con esto en ios usando react-native y keyboardAwareScroll. Estaba a punto de implementar una tonelada de código para resolver esto hasta que alguien me dio esta solución. Funcionó perfectamente.


2

si solo usas react native para que puedas usar el siguiente código

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

Además, puede usar https://docs.nativebase.io/ en su proyecto nativo de reacción y luego hacer algo como lo siguiente

<Container>

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

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

</Content>

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

</Container>

React_Native

NativeBase.io


2

Establezca android: windowSoftInputMode = "ajustarPan" en su archivo de manifiesto, y funcionará como espera.


1

Creo que la mejor y más fácil sería la siguiente, solo coloque el resto de su vista en un contenido y pie de página en una vista separada.

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

o puedes usar el pie de página de la base nativa

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

1

Sugerencia 1

=> Cuerpo con pie de página fijo

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

Imagen de demostración

Editar 2

=> Cuerpo y pie de página fijo con pestañas

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

ingrese la descripción de la imagen aquí

Notas

import {TouchableOpacity} in 'react-native'

Ventajas

Podemos usar este simple pie de página sin reaccionar la navegación inferior

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.