假设我有一个绝对位于屏幕底部的视图。此视图包含文本输入。当文本输入聚焦时,我希望视图的底部接触键盘的顶部。
我一直在搞砸键盘避免视图,但键盘一直在我的视野中。难道不能使这项工作具有绝对性吗?
我还可以尝试什么其他方法?谢谢!
几天前,我遇到了同样的问题(尽管我小时候对TextInput有一个复杂的视图),并且不仅希望TextInput得到关注,而且希望整个视图"附加"到键盘上。最终对我有用的是以下代码:
constructor(props) {
super(props);
this.paddingInput = new Animated.Value(0);
}
componentWillMount() {
this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
}
componentWillUnmount() {
this.keyboardWillShowSub.remove();
this.keyboardWillHideSub.remove();
}
keyboardWillShow = (event) => {
Animated.timing(this.paddingInput, {
duration: event.duration,
toValue: 60,
}).start();
};
keyboardWillHide = (event) => {
Animated.timing(this.paddingInput, {
duration: event.duration,
toValue: 0,
}).start();
};
render() {
return (
<KeyboardAvoidingView behavior='padding' style={{ flex: 1 }}>
[...]
<Animated.View style={{ marginBottom: this.paddingInput }}>
<TextTranslateInput />
</Animated.View>
</KeyboardAvoidingView>
);
}
其中 [..] 您有其他观点。
自定义钩子:
import { useRef, useEffect } from 'react';
import { Animated, Keyboard, KeyboardEvent } from 'react-native';
export const useKeyboardHeight = () => {
const keyboardHeight = useRef(new Animated.Value(0)).current;
useEffect(() => {
const keyboardWillShow = (e: KeyboardEvent) => {
Animated.timing(keyboardHeight, {
duration: e.duration,
toValue: e.endCoordinates.height,
useNativeDriver: true,
}).start();
};
const keyboardWillHide = (e: KeyboardEvent) => {
Animated.timing(keyboardHeight, {
duration: e.duration,
toValue: 0,
useNativeDriver: true,
}).start();
};
const keyboardWillShowSub = Keyboard.addListener(
'keyboardWillShow',
keyboardWillShow
);
const keyboardWillHideSub = Keyboard.addListener(
'keyboardWillHide',
keyboardWillHide
);
return () => {
keyboardWillHideSub.remove();
keyboardWillShowSub.remove();
};
}, [keyboardHeight]);
return keyboardHeight;
};
@jazzdle示例效果很好!谢谢你! 只需添加一次 -keyboardWillShow
方法中,可以添加event.endCoordinates.height
因此paddingBottom与键盘的高度完全相同。
keyboardWillShow = (event) => {
Animated.timing(this.paddingInput, {
duration: event.duration,
toValue: event.endCoordinates.height,
}).start();
}
React Native 现在支持一个可以用于此目的的InputAccessoryView
- 即使是锚定TextInput
。
下面是一个具体示例:https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/InputAccessoryView/InputAccessoryViewExample.js
使用功能组件。这适用于iOS和Android。
useEffect(() => {
const keyboardVisibleListener = Keyboard.addListener(
Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow",
handleKeyboardVisible
);
const keyboardHiddenListener = Keyboard.addListener(
Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide",
handleKeyboardHidden
);
return () => {
keyboardHiddenListener.remove();
keyboardVisibleListener.remove();
};}, []);
const handleKeyboardVisible = (event) => {
Animated.timing(paddingInput, {
duration: event.duration,
toValue: 60,
useNativeDriver: false,
});};
const handleKeyboardHidden = (event: any) => {
Animated.timing(paddingInput, {
duration: event.duration,
toValue: 0,
useNativeDriver: false,
});};
您可以使用弹性框来底部定位元素。这是一个简单的例子——
render() {
return (
<View style={styles.container}>
<View style={styles.top}/>
<View style={styles.bottom}>
<View style={styles.input}>
<TextInput/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
top: {
flex: .8,
},
bottom: {
flex: .2,
},
input: {
width: 200,
},
});