Reagiere auf eine feste Fußzeile


128

Ich versuche, eine reaktionsfähige native App zu erstellen, die wie eine vorhandene Web-App aussieht. Ich habe eine feste Fußzeile am unteren Rand des Fensters. Hat jemand eine Idee, wie dies mit React Native erreicht werden kann?

In der vorhandenen App ist es einfach:

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

Antworten:


166

Auf den ersten Blick könnten Sie dies mit einem ScrollView tun . Ihr Container der obersten Ebene kann ein Flex-Container sein, in dem sich oben eine ScrollView und unten eine Fußzeile befindet. Fügen Sie dann in ScrollView einfach den Rest Ihrer App wie gewohnt ein.


funktioniert super =) thx, wurde gerade heightzur Fußzeile hinzugefügt und es sieht gut aus auf 4s und 6
4ega

1
Das funktioniert. Aber ich konnte nicht verstehen warum. Warum funktioniert das?
Aditi

171

Hier ist der eigentliche Code basierend auf Colins Ramsay-Antwort:

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

1
Ja, ich habe es versucht, aber ohne Flex hat es nicht funktioniert: D Danke, dass Sie es erneut versucht haben :) Und wenn Sie auf Eingabe geklickt haben, möchte ich erwähnen, dass onContentSizeChange verwendet wird. Also habe ich die Bildlaufansicht wie folgt nach oben gescrollt: onContentSizeChange = {(Breite, Höhe) => this.refs.scrollView.scrollTo ({y: this.state.onInputSelectScrollViewPaddingSize})}
Ernestyno

1
es funktioniert nicht Ich kann nicht sehen, warum es auf jeden Fall funktionieren würde
Paulo Roberto Rosa

63

Ich verwende feste Fußzeilen für Schaltflächen in meiner App. Die Art und Weise, wie ich eine feste Fußzeile implementiere, ist wie folgt:

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

Und wenn die Fußzeile nach oben bewegt werden muss, wenn beispielsweise eine Tastatur angezeigt wird, können Sie Folgendes verwenden:

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

Verwenden Sie dann {bottom: this.state.btnLocation} in Ihrer festen Fußzeilenklasse. Ich hoffe das hilft!


2
Wer 'undefined' erhält, ist kein Objekt (das "DeviceEventEmitter.addListener" auswertet), wenn er versucht, 'this.setState (...)' auf den Tastatur-Listenern auszuführen?
John Sardinha

@ JohnSardinha Versuchen Sie es import { Keyboard} from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)stattdessen.
Maxhungry

23

Sie erhalten zuerst die Dimension und können sie dann im Flex-Stil bearbeiten

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

Beim Rendern

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

Die andere Methode ist die Verwendung von Flex

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

17

@ Alexander Danke für die Lösung

Unten finden Sie genau den Code, den Sie suchen

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

Unten ist der Screenshot

ScrollView mit fester Fußzeile


Schönes Beispiel :)
Joey Rohan


7

Einfaches Zeug hier:

Wenn Sie für diesen Ansatz keine ScrollView benötigen, können Sie den folgenden Code verwenden, um Folgendes zu erreichen:

Etwas wie das

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

7

Unten finden Sie Code zum Festlegen der Fußzeile und der Elemente oben.

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

Die Art und Weise, wie ich dies getan habe, war, eine Ansicht (nennen wir es P) mit Flex 1 zu haben, und dann in dieser Ansicht 2 weitere Ansichten (C1 und C2) mit Flex 0,9 bzw. 0,1 (Sie können die Flexhöhen auf die erforderlichen Werte ändern). . Dann haben Sie im C1 eine Bildlaufansicht. Das hat bei mir perfekt funktioniert. Beispiel unten.

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

Darüber hinaus müssen die linken, rechten und unteren Stile mit dem Wert 0 angegeben werden, damit dies funktioniert.
IVI

5

Man könnte etwas Ähnliches erreichen, wenn man mit Native reagiert position: absolute

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

Es gibt jedoch einige Dinge zu beachten.

  1. absolute positioniert das Element relativ zu seinem übergeordneten Element.
  2. Möglicherweise müssen Sie die Breite und Höhe des Elements manuell einstellen.
  3. Breite und Höhe ändern sich, wenn sich die Ausrichtung ändert. Dies muss manuell verwaltet werden

Eine praktische Stildefinition würde ungefähr so ​​aussehen:

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

Ich fand die Verwendung von Flex die einfachste Lösung.

<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

Wenn Flex eine positive Zahl ist, macht es die Komponente flexibel und wird proportional zu ihrem Flex-Wert dimensioniert. Eine Komponente mit Flex auf 2 nimmt also doppelt so viel Platz ein wie eine Komponente mit Flex auf 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
Bitte erwägen Sie, Ihrer Antwort eine Erklärung hinzuzufügen.
HMD

3

Am besten verwenden Sie die Eigenschaft acceptContent

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

Wenn Sie mehrere Ansichtselemente auf dem Bildschirm haben, können Sie verwenden

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

dann schreibe auf diese Stile

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

Lief wie am Schnürchen


2

Für Android Probleme damit:

Ändern Sie in app / src / AndroidManifest.xml windowSoftInputMode wie folgt.

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

Ich hatte absolut keine Probleme damit in iOS mit React-Native und KeyboardAwareScroll. Ich wollte gerade eine Menge Code implementieren, um dies herauszufinden, bis mir jemand diese Lösung gab. Hat perfekt funktioniert.


2

Wenn Sie nur "React Native" verwenden, können Sie den folgenden Code verwenden

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

Sie können auch https://docs.nativebase.io/ in Ihrem nativen Reaktionsprojekt verwenden und dann Folgendes tun

<Container>

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

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

</Content>

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

</Container>

React_Native

NativeBase.io


2

Setzen Sie android: windowSoftInputMode = "adjustPan" in Ihre Manifestdatei, und es funktioniert wie erwartet.


1

Ich denke, das Beste und Einfachste wäre, wie unten, platzieren Sie einfach den Rest Ihrer Ansicht in einem Inhalt und die Fußzeile in einer separaten Ansicht.

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

oder du kannst die Fußzeile von native-base verwenden

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

1

Vorschlag 1

=> Körper mit fester Fußzeile

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

Bearbeiten 2

=> Body & Fixed Footer mit 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>

Geben Sie hier die Bildbeschreibung ein

Anmerkungen

import {TouchableOpacity} in 'react-native'

Vorteile

Wir können diese einfache Fußzeile verwenden, ohne auf die untere Navigation zu reagieren

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.