【问题标题】:Make an item stick to the bottom using flex in react-native在 react-native 中使用 flex 使项目粘在底部
【发布时间】:2016-12-17 15:27:40
【问题描述】:

假设这是布局:

<View style={styles.container}>
    <View style={styles.titleWrapper}>
        ...
        ...
    </View>
    <View style={styles.inputWrapper}>
        ...
        ...
    </View>

    <View style={styles.footer}>
        <TouchableOpacity>
            <View style={styles.nextBtn}>
                <Text style={styles.nextBtnText}>Next</Text>
            </View>
        </TouchableOpacity>
    </View>
</View>

我想让带有页脚样式的视图位于屏幕底部。我尝试将alignSelf 属性赋予页脚,但不是将其定位在底部,而是将其定位在屏幕的右侧。如何使页脚项目坚持到底?谢谢。

【问题讨论】:

    标签: css react-native flexbox react-native-flexbox


    【解决方案1】:

    考虑到父组件仍然可以影响具有“绝对”样式的子组件的高度,这可能有点棘手,我也尝试像普通 HTML/CSS 一样执行“bottom: 0, height: 'auto'”,但它效果不太好,我可能会创建一个通用组件,以确保视图适合屏幕大小。 End result of view with contents

    组件参数

    style={{ 
      position: 'absolute',
      left: 0, 
      padding: ContainerPadding,
      top: TopOffset,
      width: ScreenWidth
    }}
    
    onLayout={(event) => {
      var {x, y, width, height} = event.nativeEvent.layout; // get the View's dimensions after 1st render
      SetTopOffset(ScreenHeight - height - HeaderHeight); // Set 'top' to: screen size - height (of view) - parent top offset (optional if no parent offset)
    }}
    

    使用 useState:

    const [TopOffset, SetTopOffset] = useState<number>(0); // Controls 'top' of screen
    
    • HeaderHeight 是添加到我所有页面组件的高度,如果您没有任何顶部间距,您可以删除此变量。 (currently set to 64 default and this variable is updated based on device)
    • ScreenWidth & ScreenHeight 在这里计算:export const ScreenWidth = Dimensions.get('screen').width; export const ScreenHeight = Dimensions.get('screen').height;
    • ContainerPadding 是我的项目中使用的通用填充数字(currently set to 12.5)

    【讨论】:

      【解决方案2】:

      考虑一个屏幕结构

      <View style={styles.container}>
        <View style={styles.body}> ... </View>
        <View style={styles.footer}>...</View>
      </View>
      

      您可以使用利用 flex-grow 的 Flexbox 方法干净利落地完成。

      const Styles = StyleSheet.create({
        container:{
          flexDirection: 'column', // inner items will be added vertically
          flexGrow: 1,            // all the available vertical space will be occupied by it
          justifyContent: 'space-between' // will create the gutter between body and footer
        },
      })
      

      注意:在嵌套元素的情况下,使用 flexGrow 时必须确保父容器有足够的高度。在父母和孩子上设置背景颜色以进行调试。

      【讨论】:

        【解决方案3】:

        你可以使用这种风格:

        row: {
            flexDirection: 'row',
            height: 50,
            justifyContent: 'center',
            alignItems: 'center',
            position: 'absolute', //Here is the trick
            bottom: 0,
        }
        

        【讨论】:

        • 完美答案。真的工作。只需要添加两行。位置和底部。
        【解决方案4】:

        绝对位置是另一种固定页脚的方法,就像:

        footer: {
            position: 'absolute',
            height: 40,
            left: 0, 
            top: WINDOW_HEIGHT - 40, 
            width: WINDOW_WIDTH,
        }
        

        【讨论】:

        • 当文本输入以这种方式定位时,输入时被键盘覆盖,因为输入不会上升,因为它具有绝对位置。
        【解决方案5】:

        对我来说,答案是为元素创建一个容器视图,然后为样式创建一个容器视图。

        bottomContainer: {
            flex: 1,
            justifyContent: 'flex-end',
        }
        

        【讨论】:

          【解决方案6】:

          要将View 固定到底部,只需使用:marginTop: 'auto'

          在网上搜索了一个小时后,这对我有用。我试过了,效果很好!

          【讨论】:

            【解决方案7】:

            我有一个案例,我必须像这样在bottom 中显示image,因为你可以看到sky-blue imagenot poped-upkeyboard

            为此,我为底部的图像创建了一个功能组件。

            import React, { useEffect, useState } from "react";
            import { Keyboard, View, Image } from "react-native";
            
            export const BottomImage = (props) => {
            
            const [shouldShow, showImage] = useState(true);
            
            useEffect(() => {
                Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
                Keyboard.addListener("keyboardDidHide", _keyboardDidHide);
            
                return () => {
                    Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
                    Keyboard.removeListener("keyboardDidHide", _keyboardDidHide);
                };
            }, []);
            
            let _keyboardDidShow = () => {
                showImage(false)
            }
            
            let _keyboardDidHide = () => {
                showImage(true)
            }
            
            
            return (<ViewToRender show={shouldShow} src={props.image} />)
            }
            
            function ViewToRender(props) {
            return props.show ? <Image style={{ position: 'absolute', bottom: 0 }} source={props.src} /> : <View />
            }

            要使用此底部图像,您必须将图像传递给它:

            <BottomImage image={AppImage.signupbottom} />
            

            【讨论】:

              【解决方案8】:
              import React from 'react'
              import { View, StyleSheet } from 'react-native'
              function moveToBottom(component) {
                return (
                  <View style={styles.container}>
                    {component}
                  </View>
                )
              }
              const styles = StyleSheet.create({
                container: {
                  flex: 1,
                  justifyContent: 'flex-end',
                  marginBottom: 36
                }
              })
              export default moveToBottom
              

              现在在我们的屏幕中,我们只需要导入:

              import moveToBottom from 'library/utils/moveToBottom'

              并包装我们的按钮:

              {
                moveToBottom(
                  <ImageButton
                    style={styles.button}
                    title={strings.onboarding.welcome.button}
                    onPress={() => {
                      this.props.navigation.navigate('Term')
                    }} />
                )
              }
              

              我对它进行了测试,我认为它是尊重布局而不将东西固定到底部的最佳选择,如果你在 react-native 之外使用 react-native-web,这是不可能的,因为人们调整大小和元素重叠每个都结束。

              来源:https://medium.com/react-native-training/position-element-at-the-bottom-of-the-screen-using-flexbox-in-react-native-a00b3790ca42

              【讨论】:

                【解决方案9】:

                在 react native 中,有一些属性,如 position: 'absolute', bottom: 0,,您需要将其提供给按钮视图

                【讨论】:

                  【解决方案10】:

                  为此,您可以使用样式表元素位置:'absolute'。

                  /*This is an Example to Align a View at the Bottom of Screen in React Native */
                  import React, { Component } from 'react';
                  import { StyleSheet, View, Text } from 'react-native';
                  export default class App extends Component {
                    render() {
                      return (
                        <View style={styles.containerMain}>
                          <Text> Main Content Here</Text>
                          <View style={styles.bottomView}>
                            <Text style={styles.textStyle}>Bottom View</Text>
                          </View>
                        </View>
                      );
                    }
                  }
                  const styles = StyleSheet.create({
                    containerMain: {
                      flex: 1,
                      alignItems: 'center',
                      justifyContent: 'center',
                    },
                    bottomView: {
                      width: '100%',
                      height: 50,
                      backgroundColor: '#EE5407',
                      justifyContent: 'center',
                      alignItems: 'center',
                      position: 'absolute', //Here is the trick
                      bottom: 0, //Here is the trick
                    },
                    textStyle: {
                      color: '#fff',
                      fontSize: 18,
                    },
                  });
                  

                  【讨论】:

                    【解决方案11】:

                    在 React Native 中,flexDirection 的默认值是 column(不像在 CSS 中,它是 row)。

                    因此,在flexDirection: 'column' 中,横轴是水平的,alignSelf 向左/向右工作。

                    要将您的页脚固定在底部,请将justifyContent: 'space-between' 应用于容器

                    【讨论】:

                      【解决方案12】:

                      在滚动视图中嵌入其他内容

                      <View style={styles.container}>
                      
                        <ScrollView> {/* <- Add this */}
                              <View style={styles.titleWrapper}>
                                  ...
                              </View>
                              <View style={styles.inputWrapper}>
                                  ...
                              </View>
                          </ScrollView>
                      
                          <View style={styles.footer}>
                              ...
                          </View>
                      </View>    
                      

                      【讨论】:

                        【解决方案13】:

                        我会使用以下方法:

                        <View style={styles.container}>
                        
                            <View style={styles.contentContainer}> {/* <- Add this */}
                        
                                <View style={styles.titleWrapper}>
                                    ...
                                </View>
                                <View style={styles.inputWrapper}>
                                    ...
                                </View>
                        
                            </View>
                        
                            <View style={styles.footer}>
                                ...
                            </View>
                        </View>
                        
                        var styles = StyleSheet.create({
                            container: {
                                flex: 1,
                                backgroundColor: '#F5FCFF',
                            },
                            titleWrapper: {
                        
                            },
                            inputWrapper: {
                        
                            },
                            contentContainer: {
                                flex: 1 // pushes the footer to the end of the screen
                            },
                            footer: {
                                height: 100
                            }
                        });
                        

                        这样titleWrapperinputWrapper 的样式可以在不破坏应用布局的情况下更新,并且组件本身更易于重用:)

                        【讨论】:

                          猜你喜欢
                          • 2018-05-09
                          • 2016-05-28
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-06-21
                          • 2016-03-11
                          • 2016-04-15
                          • 1970-01-01
                          相关资源
                          最近更新 更多