在 react-native 中使用 flex 使项目粘在底部
Make an item stick to the bottom using flex in react-native
假设这是布局:
<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
属性 提供给页脚,但它没有定位在底部,而是定位在屏幕的右侧。如何让页脚项目坚持到最后?谢谢。
在 React Native 中,flexDirection
的默认值是 column
(与 CSS 不同,它是 row
)。
因此,在 flexDirection: 'column'
中,横轴是水平的,alignSelf
有效 left/right。
要将页脚固定在底部,请将 justifyContent: 'space-between'
应用于容器
绝对位置是另一种固定页脚的方法,就像:
footer: {
position: 'absolute',
height: 40,
left: 0,
top: WINDOW_HEIGHT - 40,
width: WINDOW_WIDTH,
}
我会使用以下方法:
<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
}
});
这样 titleWrapper
和 inputWrapper
的样式可以在不破坏应用程序布局的情况下更新,并且组件本身更易于重用:)
在滚动视图中嵌入其他内容
<View style={styles.container}>
<ScrollView> {/* <- Add this */}
<View style={styles.titleWrapper}>
...
</View>
<View style={styles.inputWrapper}>
...
</View>
</ScrollView>
<View style={styles.footer}>
...
</View>
</View>
为此,您可以使用样式表元素位置:'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,
},
});
在 React Native 中,有一些属性,例如 position: 'absolute', bottom: 0,
,您需要将其提供给按钮视图
考虑一个屏幕结构
<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
},
})
注意:在嵌套元素的情况下,您必须确保 parent 容器在使用 flexGrow 时有足够的高度。在 parents 和 child 上设置 backgroundColor 以进行调试。
对我来说,答案是先为元素创建容器视图,然后再为样式创建容器视图。
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
}
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-web 除了 react-native,这是不可能的,因为人们调整大小和元素每一个重叠。
我有一个案例,我必须像这样在 bottom
中显示一个 image
,你可以看到 sky-blue
image
是 not
poped-up
与 keyboard
.
为此我在底部创建了一个图像功能组件。
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} />
你可以使用这种风格:
row: {
flexDirection: 'row',
height: 50,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute', //Here is the trick
bottom: 0,
}
要将 View
固定在底部,只需使用:marginTop: 'auto'
.
在网上搜索了大约一个小时后,这对我有用。我试过并且成功了!
这可能有点棘手,因为父组件仍然会影响具有 'absolute' 样式的子组件的高度,我也尝试像正常一样执行“bottom: 0, height: 'auto'” HTML/CSS,但效果不佳,接下来我可能会创建一个通用组件,以确保视图适合屏幕尺寸。 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)
}}
使用状态:
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)
本质上是快速示例,基于@David 的回答:
<View style={{flex: 1}}>
<View style={{flex: 1}}>
<Text>Main content</Text>
</View>
<Text>Footer</Text>
</View>
假设这是布局:
<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
属性 提供给页脚,但它没有定位在底部,而是定位在屏幕的右侧。如何让页脚项目坚持到最后?谢谢。
在 React Native 中,flexDirection
的默认值是 column
(与 CSS 不同,它是 row
)。
因此,在 flexDirection: 'column'
中,横轴是水平的,alignSelf
有效 left/right。
要将页脚固定在底部,请将 justifyContent: 'space-between'
应用于容器
绝对位置是另一种固定页脚的方法,就像:
footer: {
position: 'absolute',
height: 40,
left: 0,
top: WINDOW_HEIGHT - 40,
width: WINDOW_WIDTH,
}
我会使用以下方法:
<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
}
});
这样 titleWrapper
和 inputWrapper
的样式可以在不破坏应用程序布局的情况下更新,并且组件本身更易于重用:)
在滚动视图中嵌入其他内容
<View style={styles.container}>
<ScrollView> {/* <- Add this */}
<View style={styles.titleWrapper}>
...
</View>
<View style={styles.inputWrapper}>
...
</View>
</ScrollView>
<View style={styles.footer}>
...
</View>
</View>
为此,您可以使用样式表元素位置:'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,
},
});
在 React Native 中,有一些属性,例如 position: 'absolute', bottom: 0,
,您需要将其提供给按钮视图
考虑一个屏幕结构
<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
},
})
注意:在嵌套元素的情况下,您必须确保 parent 容器在使用 flexGrow 时有足够的高度。在 parents 和 child 上设置 backgroundColor 以进行调试。
对我来说,答案是先为元素创建容器视图,然后再为样式创建容器视图。
bottomContainer: {
flex: 1,
justifyContent: 'flex-end',
}
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-web 除了 react-native,这是不可能的,因为人们调整大小和元素每一个重叠。
我有一个案例,我必须像这样在 bottom
中显示一个 image
,你可以看到 sky-blue
image
是 not
poped-up
与 keyboard
.
为此我在底部创建了一个图像功能组件。
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} />
你可以使用这种风格:
row: {
flexDirection: 'row',
height: 50,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute', //Here is the trick
bottom: 0,
}
要将 View
固定在底部,只需使用:marginTop: 'auto'
.
在网上搜索了大约一个小时后,这对我有用。我试过并且成功了!
这可能有点棘手,因为父组件仍然会影响具有 'absolute' 样式的子组件的高度,我也尝试像正常一样执行“bottom: 0, height: 'auto'” HTML/CSS,但效果不佳,接下来我可能会创建一个通用组件,以确保视图适合屏幕尺寸。 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)
}}
使用状态:
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)
本质上是快速示例,基于@David 的回答:
<View style={{flex: 1}}>
<View style={{flex: 1}}>
<Text>Main content</Text>
</View>
<Text>Footer</Text>
</View>