React Native "interactive" keyboardDismissMode 在拖动时抛出错误
React Native "interactive" keyboardDismissMode throws error when dragged
错误是:RCTLayoutAnimationGroup expects timings to be in ms, not seconds
当我快速向下拖动键盘时出现这种情况。有时候这种情况会发生;有时不会。
我在 KeyboardAvoidingView 中使用一个简单的 TextInput 组件
将 bounces={false} 添加到您的 ScrollView 似乎可以解决问题。
<ScrollView keyboardDismissMode="interactive" bounces={false}>
它也稍微改变了行为,但是错误似乎不再出现了。
我认为如果您希望保持 ScrollView 的 'bouncy' 行为,最好的方法是使 'bounces' 依赖于键盘显示。显示键盘时,弹跳设置为 false。看看我的示例组件:
export default class App extends Component<Props> {
constructor(){
super();
this.state = {
bounces: true
}
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
}
_keyboardDidShow(){
this.setState({bounces: false});
}
_keyboardDidHide(){
this.setState({bounces: true});
}
render() {
return (
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
<ScrollView keyboardDismissMode="interactive" bounces={this.state.bounces}>
<TextInput
style={{height: 40, width: 150, borderColor: 'gray', borderWidth: 1}}
/>
</ScrollView>
</KeyboardAvoidingView>
);
}
}
编辑:
当持续时间小于 10(ms) 时,RNT hack 将覆盖持续时间。对你来说应该是改变:node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js 方法:scheduleLayoutAnimation 改变:
const {duration, easing, endCoordinates} = event;
至:
let {duration, easing, endCoordinates} = event;
并添加:
if(duration < 10){
duration = 10;
}
在 if (duration && easing) 条件内。
这将确保最短持续时间为 1 毫秒且绝不会更短,因此不会再抛出持续时间。
我的 KeyboardAvoidingView.js, _onKeyboardChange 方法看起来像这样:
_onKeyboardChange = (event: ?KeyboardEvent) => {
if (event == null) {
this.setState({bottom: 0});
return;
}
let {duration, easing, endCoordinates} = event;
const height = this._relativeKeyboardHeight(endCoordinates);
if (this.state.bottom === height) {
return;
}
if (duration && easing) {
if(duration < 10){
duration = 10;
}
LayoutAnimation.configureNext({
duration: duration,
update: {
duration: duration,
type: LayoutAnimation.Types[easing] || 'keyboard',
},
});
}
this.setState({bottom: height});
};
编辑 2:
我向 RNT 团队提交了一个问题,并向他们打开了一个 PR:https://github.com/facebook/react-native/pull/21858
编辑 3:
修复已合并以响应本机主控:https://github.com/facebook/react-native/commit/87b65339379362f9db77ae3f5c9fa8934da34b25
错误是:RCTLayoutAnimationGroup expects timings to be in ms, not seconds
当我快速向下拖动键盘时出现这种情况。有时候这种情况会发生;有时不会。
我在 KeyboardAvoidingView 中使用一个简单的 TextInput 组件
将 bounces={false} 添加到您的 ScrollView 似乎可以解决问题。
<ScrollView keyboardDismissMode="interactive" bounces={false}>
它也稍微改变了行为,但是错误似乎不再出现了。
我认为如果您希望保持 ScrollView 的 'bouncy' 行为,最好的方法是使 'bounces' 依赖于键盘显示。显示键盘时,弹跳设置为 false。看看我的示例组件:
export default class App extends Component<Props> {
constructor(){
super();
this.state = {
bounces: true
}
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
}
_keyboardDidShow(){
this.setState({bounces: false});
}
_keyboardDidHide(){
this.setState({bounces: true});
}
render() {
return (
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
<ScrollView keyboardDismissMode="interactive" bounces={this.state.bounces}>
<TextInput
style={{height: 40, width: 150, borderColor: 'gray', borderWidth: 1}}
/>
</ScrollView>
</KeyboardAvoidingView>
);
}
}
编辑:
当持续时间小于 10(ms) 时,RNT hack 将覆盖持续时间。对你来说应该是改变:node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js 方法:scheduleLayoutAnimation 改变:
const {duration, easing, endCoordinates} = event;
至:
let {duration, easing, endCoordinates} = event;
并添加:
if(duration < 10){
duration = 10;
}
在 if (duration && easing) 条件内。
这将确保最短持续时间为 1 毫秒且绝不会更短,因此不会再抛出持续时间。
我的 KeyboardAvoidingView.js, _onKeyboardChange 方法看起来像这样:
_onKeyboardChange = (event: ?KeyboardEvent) => {
if (event == null) {
this.setState({bottom: 0});
return;
}
let {duration, easing, endCoordinates} = event;
const height = this._relativeKeyboardHeight(endCoordinates);
if (this.state.bottom === height) {
return;
}
if (duration && easing) {
if(duration < 10){
duration = 10;
}
LayoutAnimation.configureNext({
duration: duration,
update: {
duration: duration,
type: LayoutAnimation.Types[easing] || 'keyboard',
},
});
}
this.setState({bottom: height});
};
编辑 2:
我向 RNT 团队提交了一个问题,并向他们打开了一个 PR:https://github.com/facebook/react-native/pull/21858
编辑 3: 修复已合并以响应本机主控:https://github.com/facebook/react-native/commit/87b65339379362f9db77ae3f5c9fa8934da34b25