React-native 解决TextInput在OPPO手机中无法调起键盘的问题

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();

}

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值