React Native 固定页脚

Posted

技术标签:

【中文标题】React Native 固定页脚【英文标题】:React Native fixed footer 【发布时间】:2015-06-09 11:02:34 【问题描述】:

我尝试创建看起来像现有网络应用程序的反应原生应用程序。我在窗口底部有一个固定的页脚。有谁知道如何通过 react native 实现这一点?

在现有应用中很简单:

.footer 
  position: fixed;
  bottom: 0;

【问题讨论】:

【参考方案1】:

我使用了height: 100%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>

【讨论】:

【参考方案2】:

当 flex 为正数时,它使组件变得灵活,并且它的大小将与其 flex 值成正比。因此 flex 设置为 2 的组件将占用两倍于 flex 设置为 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>

【讨论】:

请考虑为您的答案添加一些解释。【参考方案3】:

建议 1

=> 带有固定页脚的正文

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

编辑 2

=> 带有标签的正文和固定页脚

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

备注

import TouchableOpacity from 'react-native'

优势

我们可以使用这个简单的页脚而不用响应底部导航

【讨论】:

【参考方案4】:

我创建了一个包。它可能会满足您的需求。

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>

【讨论】:

【参考方案5】:

我在我的应用中为按钮使用固定页脚。我实现固定页脚的方式是这样的:

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

如果需要在出现键盘时将页脚向上移动,例如,您可以使用:

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)
  

然后在您的固定页脚类中使用 bottom: this.state.btnLocation。我希望这会有所帮助!

【讨论】:

在键盘监听器上尝试执行“this.setState(...)”时,任何人都得到“未定义不是对象(评估“DeviceEventEmitter.addListener”)”? @JohnSardinha 改用import Keyboard from 'react-native'; Keyboard.addListener('keyboardWillShow', this.showHandler)【参考方案6】:
import Dimensions from 'react-native'

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

然后就写这个样式

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

像魅力一样工作

【讨论】:

【参考方案7】:

下面是在上面设置页脚和元素的代码。

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

【讨论】:

【参考方案8】:

我认为最好和最简单的方法如下所示,只需将视图的其余部分放在内容中,将页脚放在单独的视图中。

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

或者你可以使用原生基础的页脚

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

【讨论】:

【参考方案9】:

在您的清单文件中设置 android:windowSoftInputMode="adjustPan",它会按您的预期工作。

【讨论】:

【参考方案10】:

如果你只是使用 react native 那么你可以使用下面的代码

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

另外,你可以在你的 react native 项目中使用https://docs.nativebase.io/,然后执行如下操作

<Container>

/*Your Main Content*/
<Content>

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

</Content>

/*Your Footer*/
<Footer>
   /*Elements*/
</Footer>

</Container>

React_Native

NativeBase.io

【讨论】:

【参考方案11】:

对于与此有关的 Android 问题:

在 app/src/AndroidManifest.xml 中将 windowSoftInputMode 更改为以下内容。

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

我在 ios 中使用 react-native 和 keyboardAwareScroll 完全没有问题。我正要实现大量代码来解决这个问题,直到有人给我这个解决方案。完美运行。

【讨论】:

【参考方案12】:

我发现使用 flex 是最简单的解决方案。

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

【讨论】:

【参考方案13】:

使用position: absolute 可以在本机反应中实现类似的效果

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

不过有几件事要记住。

    absolute 相对于其父元素定位元素。 您可能需要手动设置元素的宽度和高度。 宽度和高度会随着方向的改变而改变。这必须手动管理

实用的样式定义如下所示:

import  Dimensions  from 'react-native';

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

let footerStyle = 
  position: 'absolute',
  bottom: 0,
  width: screenWidth,
  height: 60

【讨论】:

【参考方案14】:

简单的东西在这里:

如果您不需要 ScrollView 来使用这种方法,您可以使用下面的代码来实现这样的事情:

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

【讨论】:

【参考方案15】:

这是基于 Colin 的 Ramsay 答案的实际代码:

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

【讨论】:

是的,我试过了,但没有 flex 没有用 :D 感谢您再次尝试 :) 如果您单击输入,我想提一下使用 onContentSizeChange。所以我做了什么,我像这样滚动滚动视图: onContentSizeChange= (width, height) => this.refs.scrollView.scrollTo( y: this.state.onInputSelectScrollViewPaddingSize ) 它不起作用。我不明白为什么它适用于任何情况【参考方案16】:

最好的方法是使用 justifyContent 属性

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

如果屏幕上有多个视图元素,则可以使用

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

【讨论】:

【参考方案17】:

我这样做的方法是创建一个带有 flex 1 的视图(我们称之为 P),然后在该视图内有另外 2 个视图(C1 和 C2)分别使用 flex 0.9 和 0.1(您可以将 flex 高度更改为所需的值)。然后,在 C1 里面有一个滚动视图。这对我来说非常有效。下面的例子。

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

【讨论】:

除此之外,必须提供值 0 的左、右和下样式才能使其工作。【参考方案18】:

您可能还想看看 NativeBase (http://nativebase.io)。这是一个 React Native 组件库,其中包含一些不错的布局结构 (http://nativebase.io/docs/v2.0.0/components#anatomy),包括页眉和页脚。

有点像 Bootstrap for Mobile。

【讨论】:

它不包括固定页脚的布局。【参考方案19】:

在我的脑海中,您可以使用ScrollView 来做到这一点。你的***容器可以是一个 flex 容器,里面有一个顶部的 ScrollView 和底部的页脚。然后在 ScrollView 中正常放置应用程序的其余部分。

【讨论】:

效果很好 =) thx,刚刚在页脚视图中添加了height,它在 4s 和 6 上看起来不错 这行得通。但我不明白为什么。为什么会这样? @Aditi 如果我理解正确,那是因为 ScrollView 设置为使用屏幕上所有可用的高度。第二个容器只会占用它需要的空间——例如,如果你将它设置为height: 10,它会占用 10 的高度。所以会有两个组件,第一个会占用所有可用空间,而第二个只需要它需要的东西,它会从第一个结束的地方开始——在屏幕的底部。【参考方案20】:

@Alexander 感谢您的解决方案

下面是你要找的代码

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

下面是截图

【讨论】:

很好的例子:)【参考方案21】:

你先得到 Dimension,然后通过 flex 样式对其进行操作

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

在渲染中

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

另一种方法是使用flex

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

【讨论】:

我正在寻找的聪明解决方案,谢谢

以上是关于React Native 固定页脚的主要内容,如果未能解决你的问题,请参考以下文章

React Native - 容器底部的粘性页脚

React Native - 顶部的 React Navigation 固定组件

React Native 溢出 Touchable 在 Android 中不起作用

我们可以在“native-base”的页脚组件的列中设置两个按钮,还是可以设置“native-base”的页脚高度?

React Native Overflow Touchable在Android中不起作用

React-Native:避免文本换行