Expo聊天应用调用ImagePicker后KeyboardAvoidingView失效问题求助
Expo聊天应用调用ImagePicker后KeyboardAvoidingView失效问题求助
我正在用Expo开发一个聊天应用,布局中已经使用了SafeAreaProvider和SafeAreaView,首页(index文件)里则用到了KeyboardAvoidingView。但是遇到一个奇怪的问题:点击首页的图片选择器之后,KeyboardAvoidingView就无法正常工作了——输入框内容会被键盘遮挡,但在点击图片选择器之前一切正常。
Layout代码
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; import { StatusBar } from 'expo-status-bar'; import 'react-native-reanimated'; import { useColorScheme } from '@/hooks/use-color-scheme'; import * as ImagePicker from 'expo-image-picker'; import { default as React, useState } from 'react'; import { Alert, Image, KeyboardAvoidingView, Platform, StyleSheet, Text, TextInput, TouchableOpacity } from 'react-native'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; import { Stack } from 'expo-router'; export const unstable_settings = { anchor: '(tabs)', }; export default function RootLayout() { const colorScheme = useColorScheme(); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [image, setImage] = useState(null); const pickImage = async () => { // Ask permission const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permission.granted) { Alert.alert('Permission required', 'Allow access to media library.'); return; } // Open picker const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.canceled) { setImage(result.assets[0].uri); } }; const handleSubmit = () => { Alert.alert( 'Form Submitted', `Name: ${name}\nEmail: ${email}\nImage: ${image ? 'Selected' : 'Not Selected'}` ); }; return ( <SafeAreaProvider> <SafeAreaView style={{ flex: 1 }}> <Stack> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="modal" options={{ presentation: 'modal', title: 'Modal' }} /> </Stack> </SafeAreaView> <StatusBar style="auto" /> </SafeAreaProvider> ); }
Index代码
import * as ImagePicker from 'expo-image-picker'; import React, { useState } from 'react'; import { Alert, Image, KeyboardAvoidingView, Platform, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; const TestScreen = () => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [image, setImage] = useState(null); const pickImage = async () => { // Ask permission const permission = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permission.granted) { Alert.alert('Permission required', 'Allow access to media library.'); return; } // Open picker const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.canceled) { setImage(result.assets[0].uri); } }; const handleSubmit = () => { Alert.alert( 'Form Submitted', `Name: ${name}\nEmail: ${email}\nImage: ${image ? 'Selected' : 'Not Selected'}` ); }; return ( <View style={styles.container}> <TouchableOpacity onPress={pickImage} style={styles.imagePicker}> {image ? ( <Image source={{ uri: image }} style={styles.image} /> ) : ( <Text style={styles.imagePlaceholder}>Tap to select image</Text> )} </TouchableOpacity> <KeyboardAvoidingView style={styles.form} behavior={Platform.OS === 'ios' ? 'padding' : undefined} > {/* Form */} <Text style={styles.label}>Name</Text> <TextInput style={styles.input} placeholder="Enter your name" value={name} onChangeText={setName} /> <Text style={styles.label}>Email</Text> <TextInput style={styles.input} placeholder="Enter your email" keyboardType="email-address" value={email} onChangeText={setEmail} /> <TouchableOpacity style={styles.button} onPress={handleSubmit}> <Text style={styles.buttonText}>Submit</Text> </TouchableOpacity> </KeyboardAvoidingView> </View>); }; const styles = StyleSheet.create({ container: { padding: 20, flex: 1, justifyContent: 'center', backgroundColor: "green", }, imagePicker: { width: '100%', height: 200, borderRadius: 12, backgroundColor: '#f2f2f2', justifyContent: 'center', alignItems: 'center', marginBottom: 20, overflow: 'hidden', }, image: { width: '100%', height: '100%', }, imagePlaceholder: { color: '#888', fontSize: 16, }, form: { gap: 10, }, label: { fontSize: 16, fontWeight: '600', }, input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 12, }, button: { backgroundColor: '#007BFF', padding: 15, borderRadius: 8, marginTop: 10, alignItems: 'center', }, buttonText: { color: '#fff', fontWeight: '600', }, }); export default TestScreen;
package.json代码
{ "name": "test-react-native", "main": "expo-router/entry", "version": "1.0.0", "scripts": { "start": "expo start", "reset-project": "node ./scripts/reset-project.js", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", "lint": "expo lint" }, "dependencies": { "@expo/vector-icons": "^15.0.3", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/elements": "^2.6.3", "@react-navigation/native": "^7.1.8", "expo": "~54.0.33", "expo-constants": "~18.0.13", "expo-font": "~14.0.11", "expo-haptics": "~15.0.8", "expo-image": "~3.0.11", "expo-image-picker": "^55.0.10", "expo-linking": "~8.0.11", "expo-router": "~6.0.23", "expo-splash-screen": "~31.0.13", "expo-status-bar": "~3.0.9", "expo-symbols": "~1.0.8", "expo-system-ui": "~6.0.9", "expo-web-browser": "~15.0.10", "react": "19.1.0", "react-dom": "19.1.0", "react-native": "0.81.5", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-web": "~0.21.0", "react-native-worklets": "0.5.1" }, "devDependencies": { "@types/react": "~19.1.0", "eslint": "^9.25.0", "eslint-config-expo": "~10.0.0", "typescript": "~5.9.2" }, "private": true }
有没有大佬能帮忙排查并解决这个问题呀?感激不尽!
备注:内容来源于stack exchange,提问作者Sayel
相关产品推荐
相关产品推荐

