bug具体是这样的,一开始进入界面可以正常弹出软键盘,然后退出界面,再次进入,软键盘就无法调起了。
首先百度了一下这个问题,发现百度上并没有什么特别好能完全解决方案。
然后因为我是学的android原生开发的,所以就先测试了一下封装原生EditText组件,然后在RN中使用,发现这样软键盘都是可以正常弹出,但是由于只是个菜鸟,不知道如何回调原生中输入的内容给RN,所以放弃了。如果有大神知道怎么回调,麻烦教学一下。(个人感觉这个方案比较是比较好的。)
然后在测试过程中发现了两种特殊情况
1、如果手机锁屏再打开,原先不能调起软键盘的界面就可以调起。
2、alter弹框之后,原先不能调起软键盘的界面也是可以调起。
我们可以考虑下这两种特殊情况处理。
先看第一种情况,锁屏再开屏,这个首先不说代码怎么实现的问题,就说用户体验也是极差的,所以这种方式不考虑。
那就剩第二种情况了。
弹框自然会想到系统自带的alter,但是这个alter太明显,而且也不好控制隐藏。我又是主做原生开发(主要是RN学的比较水),所以就想到了,直接调用原生的dialog,自定义dialog的布局,在放透明背景。
实现如下:
dialog_mydilog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="1px"
android:layout_height="1px">
</LinearLayout>
这里直接放个宽搞都是1像素的布局就行。
然后在继承自 ReactContextBaseJavaModule的Module文件下
添加如下
//定义全局变量
AlertDialog dlg;
//这个方法是弹出透明框。
@ReactMethod
public void showJp(){
if(dlg==null){
dlg = new AlertDialog.Builder(getCurrentActivity()).create();
}
dlg.show();
//dlg.setCanceledOnTouchOutside(false);//设置点击返回键或者弹框外,弹框都不会消失
Window window = dlg.getWindow();
//window.setGravity(Gravity.BOTTOM);//可以让弹框在底部弹出来
// 加载弹框布局
window.setContentView(R.layout.dialog_mydilog);
window.setBackgroundDrawableResource(R.color.transparency);//设置透明背景,不然android5.0以上会自带一个背景
}
然后这里需要一个透明颜色在res/values/color.xml 文件下新加<color name="transparency">#0000</color>
//这个方法是延时执行关闭弹框。
@ReactMethod
public void hideJp(){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(dlg!=null){
dlg.dismiss();
}
}
},2);
}
关闭弹框这里放了延时2毫秒执行是了为防止执行太快导致无效。
OK,然后在RN中有用到TextInput的界面中调用
componentDidMount() {
if(account.is_oppo){
//如果是OppO手机则弹出透明框并立即隐藏。
NativeModules.StartVideoModule.showJp();
NativeModules.StartVideoModule.hideJp();
}
}
StartVideoModule是你自己的继承自ReactContextBaseJavaModule的Module名
这里有个判断是判断手机是否是Oppo的
//这个方法是判断是否是OppO手机,根据厂商或者型号
@ReactMethod
public void isOppO(Callback callback){
if(android.os.Build.BRAND.contains("OPPO")||android.os.Build.MODEL.contains("OPPO")){
callback.invoke(true);
}else {
callback.invoke(false);
}
}
此方法最好在首界面就调用并把返回值存起来方便后面判断。
好了,按前面配置完基本上有TextInput的界面都能调起软键盘了。
但是又发现了一个问题,如果在有TextInput的界面里跳转到别的界面,再返回来这个时候TextInput又没办法调起输入框了。
聪明的人应该会想到,那我跳转回来的时候再执行下前面的弹框跟关闭代码。
确实可以,在跳转的时候加个返回函数,在下个界面返回的时候回调一下。
可惜经过测试发现,这样处理之后,还是经常会出来无法调起软键盘的情况。
观察发现是返回的时候会出现一点延迟,在后一个界面还没完全关闭的时候去弹是没有办法让前一个界面的TextInput调起软键盘的。
没办法,那我们只能在隐藏的方法里加延迟时长。经过多个时长的测试发现100毫秒的延迟能保证基本没有问题,但是返回的时候会看到一点暗一下,那是弹框的效果,延迟太低的话也是会出来TextInput无法调起软键盘的情况,暂时只能做到这个样子。
所以在返回回调中执行的应该是
ReactContextBaseJavaModule中新加
//这个方法是延时100毫秒执行关闭弹框,用于返回函数中执行,测试发现返回时立即执行或延时太快关闭,键盘还是不弹出
@ReactMethod
public void hideJp2(){
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(dlg!=null){
dlg.dismiss();
}
}
},100);
}
RN返回函数中
if(account.is_oppo){
NativeModules.StartVideoModule.showJp();
NativeModules.StartVideoModule.hideJp2();
}