好吧,我认为我已经掌握了样式。在几款不同尺寸的手机上进行了测试,看起来都很棒。然后...我在iPad上进行了测试。我的几个屏幕不在页面上。我在容器中使用flex:1,所以我不明白为什么。iPad不尊重flex:1或其他东西吗?还是我只是在皇家修改布局代码?我认为使用屏幕尺寸和%计算大多数内容对于响应式设计是可行的。
例如,登录屏幕。底部2个按钮“登录”和“主页”几乎完全在iPad屏幕上运行。在电话设备上似乎可以正常显示。
编辑:非常感谢您的答案!我已经重写了代码,现在在ipad上看起来很棒。我希望这段代码能有所改进,已将其添加到底部。现在重写所有屏幕的facepalm
import React, { useState } from "react";
import {
Dimensions,
Image,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { auth } from '../../src/config'
import AppText from "../components/AppText";
import colors from "../config/colors";
import Constants from "expo-constants";
let width = Dimensions.get('window').width;
function SignIn( { navigation } ){
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [message, setMessage] = useState('');
function emailSignIn(email, password){
email = email.trim();
auth.signInWithEmailAndPassword(email, password)
.then(function(result) {
setMessage('');
}).catch(function(error) {
setMessage('Invalid Email or Password. Sorry :(');
});
}
function updateEmail(email){
setMessage('');
setEmail(email);
}
function updatePassword(password){
setMessage('');
setPassword(password);
}
return (
<View style={styles.container}>
<Image style={styles.image} source={require("../assets/logo.png")} />
<Image style={styles.rainbow} source={require("../assets/rainbow.png")} />
<View style={styles.bottom}>
<View style={styles.inputView}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="E m a i l..."
placeholderTextColor="#003f5c"
onChangeText={(email) => updateEmail(email)}
autoCapitalize = 'none'
/>
</View>
<View style={styles.inputView2}>
<TextInput
style={{width: width * 0.8, textAlign: "center", padding: width * 0.02}}
placeholder="P a s s w o r d..."
placeholderTextColor="#003f5c"
secureTextEntry={true}
onChangeText={(password) => updatePassword(password)}
autoCapitalize = 'none'
/>
</View>
<TouchableOpacity onPress={()=> navigation.navigate('ForgotPassword')}>
<Text style={styles.forgot_button}>Forgot Password?</Text>
</TouchableOpacity>
<AppText style={styles.message}>{message}</AppText>
<TouchableOpacity onPress={()=>emailSignIn(email,password)} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>navigation.navigate('StartScreen')} style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>HOME</Text>
</TouchableOpacity>
</View>
</View>
);
}
export default SignIn;
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
paddingVertical: "3%",
width: width * 0.8,
marginBottom: 10,
},
appButtonText: {
fontSize: width * 0.04,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
bottom: {
alignItems: "center",
marginTop: width * 0.8,
},
container: {
flex: 1,
backgroundColor: colors.white,
justifyContent: "center",
alignItems: "center",
marginTop: Constants.statusBarHeight,
},
forgot_button: {
height: width * 0.1,
fontWeight: "bold",
},
image: {
width: width* 0.5,
resizeMode: "contain",
position: "absolute",
top: -20,
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
marginBottom: width * 0.05,
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
marginBottom: 0,
},
message: {
color: colors.red,
marginTop: width * 0.05,
marginBottom: 10,
alignSelf: "center",
},
rainbow: {
position: "absolute",
top: "10%",
},
});
新样式:
const styles = StyleSheet.create({
appButtonContainer: {
elevation: 8,
backgroundColor: colors.purple,
borderRadius: 30,
borderWidth: 1,
justifyContent: "center",
marginHorizontal: "5%",
height: "25%",
},
appButtonText: {
fontSize: 18,
color: colors.white,
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
letterSpacing: 10,
},
container: {
flex: 1,
backgroundColor: colors.white,
marginTop: Constants.statusBarHeight,
},
forgot_button: {
alignSelf: "center",
fontWeight: "bold",
},
image: {
height: 200,
width: 200,
},
imageContainer: {
flex: 2,
justifyContent: "center",
alignItems: "center",
},
inputButtons: {
flex: 1,
justifyContent: "space-around",
marginHorizontal: "10%",
},
inputView: {
backgroundColor: "#d9f1ff",
borderRadius: 30,
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
height: "25%",
},
inputView2: {
backgroundColor: "#ffffb8",
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
borderWidth: 1,
height: "25%",
},
message: {
color: colors.red,
alignSelf: "center",
},
rainbow: {
flex: 1,
width: "100%",
height: "100%",
position: "absolute",
},
rainbowImage: {
height: "60%",
position: "absolute",
top: "15%",
},
submitButtons: {
flex: 1,
justifyContent: "space-around",
},
});
您width
将从Dimensions
文件的顶层获得,然后在此基础上进行所有布局计算。这意味着无论何时第一次解析/运行此文件,都width
将对其进行计算。如果设备在第一次通过代码时正确报告了宽度(不保证),那将起作用,但是如果在该过程中它获得了异常的宽度(可能)则将中断,并且如果窗口更改大小或旋转,则肯定会中断。
width
建议您不要将Flexbox用于动态布局,而应将所有计算都基于该static 。
例如,在代码中的某一点,您TextInput
通过执行来将视图设置为视图的80%width * 0.8
。您可以通过将宽度设置为80%来执行相同的操作:
export default function App() {
return (
<View style={{flex: 1, justifyContent: "center", alignItems: "center"}}>
<TextInput
style={{borderWidth: 1, width: "80%"}}
/>
</View>
);
}
基本上,Dimensions
除非您确实需要,否则请尽一切可能摆脱依赖。并且,如果确实需要它,请确保在需要时根据当前屏幕进行计算,而不仅仅是在应用程序的首次运行时进行计算。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句