我已经看到了本机应用程序自动滚动窗口的这种 hack,但想知道在 React Native 中做到这一点的最佳方法......当一个<TextInput>
字段获得焦点并在视图中位于较低的位置时,键盘将覆盖文本字段。
您可以在示例 UIExplorer 的TextInputExample.js
视图中看到此问题。
有没有人有好的解决方案?
我已经看到了本机应用程序自动滚动窗口的这种 hack,但想知道在 React Native 中做到这一点的最佳方法......当一个<TextInput>
字段获得焦点并在视图中位于较低的位置时,键盘将覆盖文本字段。
您可以在示例 UIExplorer 的TextInputExample.js
视图中看到此问题。
有没有人有好的解决方案?
2017 答案
这KeyboardAvoidingView
可能是现在最好的方法。在此处查看文档。与Keyboard
module相比,它非常简单,它使开发人员可以更好地控制执行动画。Spencer Carli 在他的媒体博客上展示了所有可能的方法。
2015 答案
执行此操作的正确方法react-native
不需要外部库,利用本机代码并包括动画。
首先定义一个函数来处理onFocus
每个TextInput
(或您想要滚动到的任何其他组件)的事件:
// Scroll a component into view. Just pass the component ref string.
inputFocused (refName) {
setTimeout(() => {
let scrollResponder = this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(this.refs[refName]),
110, //additionalOffset
true
);
}, 50);
}
然后,在您的渲染函数中:
render () {
return (
<ScrollView ref='scrollView'>
<TextInput ref='username'
onFocus={this.inputFocused.bind(this, 'username')}
</ScrollView>
)
}
这使用RCTDeviceEventEmitter
for 键盘事件和大小调整,使用 测量组件的位置RCTUIManager.measureLayout
,并计算scrollResponderInputMeasureAndScrollToKeyboard
.
您可能想要使用该additionalOffset
参数,以满足您特定 UI 设计的需要。
我们结合了一些来自 react-native-keyboard-spacer 的代码和来自@Sherlock 的代码来创建一个 KeyboardHandler 组件,该组件可以包裹在任何带有 TextInput 元素的 View 周围。奇迹般有效!:-)
/**
* Handle resizing enclosed View and scrolling to input
* Usage:
* <KeyboardHandler ref='kh' offset={50}>
* <View>
* ...
* <TextInput ref='username'
* onFocus={()=>this.refs.kh.inputFocused(this,'username')}/>
* ...
* </View>
* </KeyboardHandler>
*
* offset is optional and defaults to 34
* Any other specified props will be passed on to ScrollView
*/
'use strict';
var React=require('react-native');
var {
ScrollView,
View,
DeviceEventEmitter,
}=React;
var myprops={
offset:34,
}
var KeyboardHandler=React.createClass({
propTypes:{
offset: React.PropTypes.number,
},
getDefaultProps(){
return myprops;
},
getInitialState(){
DeviceEventEmitter.addListener('keyboardDidShow',(frames)=>{
if (!frames.endCoordinates) return;
this.setState({keyboardSpace: frames.endCoordinates.height});
});
DeviceEventEmitter.addListener('keyboardWillHide',(frames)=>{
this.setState({keyboardSpace:0});
});
this.scrollviewProps={
automaticallyAdjustContentInsets:true,
scrollEventThrottle:200,
};
// pass on any props we don't own to ScrollView
Object.keys(this.props).filter((n)=>{return n!='children'})
.forEach((e)=>{if(!myprops[e])this.scrollviewProps[e]=this.props[e]});
return {
keyboardSpace:0,
};
},
render(){
return (
<ScrollView ref='scrollView' {...this.scrollviewProps}>
{this.props.children}
<View style={{height:this.state.keyboardSpace}}></View>
</ScrollView>
);
},
inputFocused(_this,refName){
setTimeout(()=>{
let scrollResponder=this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(_this.refs[refName]),
this.props.offset, //additionalOffset
true
);
}, 50);
}
}) // KeyboardHandler
module.exports=KeyboardHandler;
首先你需要安装react-native-keyboardevents。
然后回到 javascript 领域:
您需要导入 react-native-keyboardevents。
var KeyboardEvents = require('react-native-keyboardevents');
var KeyboardEventEmitter = KeyboardEvents.Emitter;
然后在您的视图中,为键盘空间添加一些状态并通过监听键盘事件进行更新。
getInitialState: function() {
KeyboardEventEmitter.on(KeyboardEvents.KeyboardDidShowEvent, (frames) => {
this.setState({keyboardSpace: frames.end.height});
});
KeyboardEventEmitter.on(KeyboardEvents.KeyboardWillHideEvent, (frames) => {
this.setState({keyboardSpace: 0});
});
return {
keyboardSpace: 0,
};
},
最后,在你的渲染函数下面添加一个垫片,这样当它增加尺寸时,它会撞到你的东西。
<View style={{height: this.state.keyboardSpace}}></View>
也可以使用动画api,但为了简单起见,我们只在动画之后进行调整。
react-native-keyboard-aware-scroll-view 为我解决了这个问题。 GitHub 上的 react-native-keyboard-aware-scroll-view