Cha*_*eja 37 react-native-android
我正在尝试使用KeyboardAvoidingView with behavior ="padding".
出于某种原因,当我尝试在TextInput中输入任何文本时,空间将位于TextInput下方.随附的是正在发生的事情以及代码.有没有人有任何想法在这里发生什么?
render() {
return (
<KeyboardAvoidingView style={{ flex: 1}} behavior="padding">
< View
style={{
flex: 1,
backgroundColor: "#FFFFFF",
}}
>
<ScrollView
contentContainerStyle={{ justifyContent: "flex-end", flex: 1 }}>
<ChatInfo />
</ScrollView>
<View style={styles.container}>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
autoCapitalize="none"
onChangeText={text => this.setState({ text: text })}
value={this.state.text}
/>
<TouchableOpacity
style={styles.submitButton}
onPress={this.submitName}
>
<Text style={styles.submitButtonText}> SEND </Text>
</TouchableOpacity>
</View>
</ View>
</KeyboardAvoidingView>
);
}
}
export default connect()(ChatScreen);
const styles = StyleSheet.create({
input: {
margin: 2,
paddingLeft: 15,
flex: 1,
height: 40,
padding: 10,
fontSize: 14,
fontWeight: "400"
},
container: {
borderTopWidth: 1,
minWidth: "100%",
borderColor: "#cccccc",
height: 44,
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: "#fff"
},
submitButtonText: {
color: "#0a9ffc",
fontSize: 14,
fontWeight: "500"
},
submitButton: {
backgroundColor: "#fff",
padding: 10,
margin: 2,
height: 40,
alignItems: "center",
justifyContent: "center"
}
});
Run Code Online (Sandbox Code Playgroud)
Toh*_*oon 92
如果您正在使用react-navigation,则会受到react-navigation标题的影响.标题的高度在不同的移动屏幕上有所不同.所以你必须得到标题的高度并传递到keyboardVerticalOffset道具.
import { Header } from 'react-navigation';
<KeyboardAvoidingView
keyboardVerticalOffset = {Header.HEIGHT + 20} // adjust the value here if you need more padding
style = {{ flex: 1 }}
behavior = "padding" >
<ScrollView>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
</ScrollView>
</KeyboardAvoidingView>
Run Code Online (Sandbox Code Playgroud)
小智 24
这是KeyboardAvoidingView和Android的已知问题.有多种方法可以解决此问题.
React Native文档说:
如果没有任何行为道具,Android可能表现得更好,而iOS则相反.
所以,如果你只使用Android,你可以删除行为道具,它应该立即工作.为了获得最佳效果,请添加android:windowSoftInputMode="adjustResize"到您的清单中.
或者,您可以给出一个适合您的偏移值:
KeyboardAvoidingView keyboardVerticalOffset={-500} behavior="padding"
对于ios有条件地做同样的事情:
behavior= {(Platform.OS === 'ios')? "padding" : null}
keyboardVerticalOffset={Platform.select({ios: 0, android: 500})}
ful*_*ris 22
对于 2021 年来到这里的任何人,需要更新以下答案:
useHeaderHeight不再由 导出@react-navigation/stack,而是在@react-navigation/elements.
React Native现在还建议behavior为 iOS 和 Android设置该prop。所以完整的解决方案是:
import { useHeaderHeight } from '@react-navigation/elements';
export const MyComponent = () => {
const headerHeight = useHeaderHeight();
return (
<KeyboardAvoidingView
keyboardVerticalOffset={headerHeight}
style={style.container}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
{/* rest of your component */}
</KeyboardAvoidingView>
);
}
Run Code Online (Sandbox Code Playgroud)
我不需要向headerHeightin添加任何额外的值keyboardVerticalOffset,它在 iOS 和 Android 上运行得很好。
编辑:现在问题更加严重,因为KeyboardAvoidingView不支持所有类型的 Android 键盘。该解决方案必须依赖于打开键盘到特定元素(例如文本输入)。这个自定义组件看起来像这样:
import React, { PropsWithChildren, useEffect, useState } from 'react';
import { Platform, Animated, Dimensions, Keyboard, KeyboardAvoidingView, StyleSheet, TextInput } from 'react-native';
import {useHeaderHeight} from '@react-navigation/elements';
import { useKeyboard } from '@react-native-community/hooks';
export default function KeyboardShift (props: PropsWithChildren<{}>) {
const [shift, setShift] = useState(new Animated.Value(0))
const keyboard = useKeyboard()
// On mount, add keyboard show and hide listeners
// On unmount, remove them
useEffect(() => {
Keyboard.addListener('keyboardDidShow', handleKeyboardDidShow);
Keyboard.addListener('keyboardDidHide', handleKeyboardDidHide);
return () => {
Keyboard.removeAllListeners('keyboardDidShow');
Keyboard.removeAllListeners('keyboardDidHide');
}
}, [])
const handleKeyboardDidShow = () => {
const { height: windowHeight } = Dimensions.get('window');
const keyboardHeight = keyboard.keyboardHeight;
const currentlyFocusedInputRef = TextInput.State.currentlyFocusedInput();
currentlyFocusedInputRef.measure((x, y, width, height, pageX, pageY) => {
const fieldHeight = height;
const fieldTop = pageY;
const gap = (windowHeight - keyboardHeight) - (fieldTop + fieldHeight);
if (gap >= 0) {
return;
}
Animated.timing(
shift,
{
toValue: gap,
duration: 1000,
useNativeDriver: true,
}
).start();
})
}
const handleKeyboardDidHide = () => {
Animated.timing(
shift,
{
toValue: 0,
duration: 1000,
useNativeDriver: true,
}
).start();
}
const { children } = props;
// Android: we need an animated view since the keyboard style can vary widely
// And React Native's KeyboardAvoidingView isn't always reliable
if (Platform.OS === 'android') {
return (
<Animated.View style={[styles.container, { transform: [{translateY: shift}] }]}>
{children}
</Animated.View>
);
}
// iOS: React Native's KeyboardAvoidingView with header offset and
// behavior 'padding' works fine on all ios devices (and keyboard types)
const headerHeight = useHeaderHeight();
return (
<KeyboardAvoidingView
keyboardVerticalOffset={headerHeight}
style={styles.container}
behavior={'padding'}>
{children}
</KeyboardAvoidingView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
Run Code Online (Sandbox Code Playgroud)
是的,不幸的是,它很冗长,但它可以为 iOS 和 Android 上的所有类型的手机完成工作。
在这里阅读更多相关信息。
第二次编辑:截至 2022 年 4 月 22 日,我已将上面的复杂解决方案替换为以下内容:
步骤1:
behavior={Platform.OS === "ios" ? "padding" : undefined}
Run Code Online (Sandbox Code Playgroud)
第2步:
请务必删除
android:windowSoftInputMode="adjustPan"
Run Code Online (Sandbox Code Playgroud)
(或任何windowSoftInputMode与此相关的内容)来自您的AndroidManifest.xml文件。
到目前为止,这个解决方案一直有效(并且代码更少 - 总是更好,对吧?)
小智 15
本KeyboardAvoidingView必须是一个ScrollView孩子,而不是周围的其他方法。这样它表现正常(我使用它的目的是正常的)。试试吧,让我知道它是怎么回事。
<ScrollView>
<KeyboardAvoidingView styles={styles.container} behavior='padding'>
</KeyboardAvoidingView>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)
这似乎只是一个部分解决方案,虽然它最初工作,如果Android手机被锁定在屏幕上,键盘避免布局,当你解锁时最终再次使用键盘上方的额外填充.
android:windowSoftInputMode="adjustResize"从中删除AndroidManifest.xml
...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
>
...
Run Code Online (Sandbox Code Playgroud)
...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>
...
Run Code Online (Sandbox Code Playgroud)
如果我正确地理解了这个问题,我一直在处理同样的事情.通过android:windowSoftInputMode="adjustResize"在清单中,android系统将尝试做同样的工作KeyboardAvoidingView.这导致仅在Android上的键盘上方添加额外的间距.
如果在两个平台上工作,那么每次使用键盘输入时都要在iOS上处理这个问题,所以最好android:windowSoftInputMode="adjustResize"从清单中删除Android特定的行为并KeyboardAvoidingView每次使用.
小智 9
我认为这是因为行为道具的价值,所以我认为在键盘避免视图中添加这一行会有所帮助
<KeyboardAvoidingView
style = {{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : null}>
</KeyboardAvoidingView>
Run Code Online (Sandbox Code Playgroud)
KeyboardAvoidingView 的主要问题是;缺乏对其工作原理的理解。
我发现下面的链接非常有帮助
https://medium.com/@nickyang0501/keyboardavoidingview-not-working-properly-c413c0a200d4
希望能帮助到你
对于 React Native Navigation v5,您可以使用以下内容:
import { useHeaderHeight } from '@react-navigation/stack';
...
const Component = () => (
<KeyboardAvoidingView
keyboardVerticalOffset={ useHeaderHeight() } // <-- for v5
behavior="padding"
style={{ flex: 1 }}
>
<TextInput
style={{ height: 30, width: "100%, borderWidth: 1 }}
/>
</KeyboardAvoidingView
)
Run Code Online (Sandbox Code Playgroud)
https://reactnavigation.org/docs/stack-navigator#headertransparent
| 归档时间: |
|
| 查看次数: |
32043 次 |
| 最近记录: |