React Native Android 安卓监听键盘backs

2018-04-07  本文已影响323人  SunnyEver0

纪念项目开发在获取backspace监听事件时所遇到的坑。

项目的需求是当用户点击backspace时若当前输入框已无其他输入,则删除前一个联系人(类似于发送信息时删除联系人)。

1.查询RN官方资料

RN官方是未开放出TextInput输入时,键盘按钮输入的返回事件。具体原因看了一下,是由于安卓监听键盘事件太容易造成监听回调的耗损,故没有开放。所以只有自己动手去监听键盘的点击。

2.监听activity的键盘keyUp事件

可以很容易得到android开发中监听键盘按钮点击的返回事件。可在MainActivity中添加以下代码获取回调,目前只能获取backspace的按钮事件,估计android对于其他按钮的进行了过滤防止回调频繁引起的性能问题。


      @Override  // <--- Add this method if you want to react to keyUp
      public boolean onKeyUp(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);

        //  有两种方式可选
        //  1.  覆盖默认键盘监听事件
        //    super.onKeyUp(keyCode, event);
        //    return true;

        //  2. 保持原生的键盘监听事件
        //    return super.onKeyUp(keyCode, event);

        // 这里我们直接覆盖已有事件
        super.onKeyUp(keyCode, event);
        return true;
      }

我们可以此时获取事件,通过DeviceEmiiter返回给JS端,下面给出一些关键代码:

 public void onKeyUpEvent(int keyCode, KeyEvent keyEvent) {
        if (mJSModule == null) {
            //mReactContext在初始化nativeModulesPackage时传递过来
            mJSModule = mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
        }
        //发送监听给JS端
        mJSModule.emit("onKeyUp", getJsEventParams(keyCode, keyEvent, null));
 };

private WritableMap getJsEventParams(int keyCode, KeyEvent keyEvent, Integer repeatCount) {
        WritableMap params = new WritableNativeMap();
        int action = keyEvent.getAction();

        if (keyEvent.getAction() == KeyEvent.ACTION_MULTIPLE && keyCode == KeyEvent.KEYCODE_UNKNOWN) {
            String chars = keyEvent.getCharacters();
            if (chars != null) {
                params.putString("characters", chars);
            }
        }

        if (repeatCount != null) {
            params.putInt("repeatcount", repeatCount);
        }

        params.putInt("keyCode", keyCode);
        params.putInt("action", action);

        return params;
  }

如未使用的React-Native-Navigation,则项目已经成功达成我们的需求了。但在使用React-Native-Navigation之后,死活无法获取键盘输入时的回调。

3.使用React-Native-Navigation后续的坑

由于一直无法获取监听回调,理了一下可能的原因

由于当时把精力集中在第一点上,在和同事讨论之后,他的建议是能在原生层获取当前viewID然后在原生层进行包装warpper手动截取其keyUp事件。所以我们通过以下方式在JS层传递viewID给原生层,然后利用原生的findViewById获取当前view,然后我们即可为所欲为。以下为此方法的代码:

import { TextInput,findNodeHandle } from 'React-Native';

...

render() {
  return (
    <View>
      <TextInput ref="textInput">
        ...
      </TextInput >
    </View>
  );
},

somethingLikeComponentDidMount() {
  const customViewNativeID = findNodeHandle(this.refs.textInput);
  // 将id传给原生层
}

但是。。。。。在原生层通过findViewById却一直返回null,想了很多办法,还是获取为null,最后不得不放弃该思路,理了一下第二条思路。会不会是React-Native-Navigation框架使用了新的activity
查看了React-Native-Navigation的源码,果然。。。
在我们使用Start***App方法之后,React-Native-Navigationpush进入其封装好的navigationActivity,且在该activity中已将该方法封装好。我们只需要修改源码,把监听发送出来即可。但还是感觉贼不爽。至此,终于把主要的坑填完了。。。
PS:
1.改源码真的是今后维护的大坑 😭
2.必须使用push的界面才能进行回调,看了React-Native-Navigation的源码,modal出来的界面,会new一个新的无法监听的activity无法监听其键盘回调事件 。

上一篇下一篇

猜你喜欢

热点阅读