键盘事件 event.key 在 android webview 上无法识别

Posted

技术标签:

【中文标题】键盘事件 event.key 在 android webview 上无法识别【英文标题】:Keyboard event event.key is unidentified on android webview 【发布时间】:2021-09-04 23:50:12 【问题描述】:

尝试在 react native 上使用此 html 加载 webview

    <div
          tabindex="1"
          contenteditable="true"
          id="test-test"
          style="width: 300px; height: 300px;"
        >
   </div>
   <script>
          document
            .getElementById(“test-test”)
            .addEventListener(“keydown”, function (e) 
              alert(e.key || e.keyCode || “empty”);
            );
   </script>

event.key 无法识别或 event.keyCode 始终为 229

【问题讨论】:

试试e.charCode 对于 android 键盘,charCode 始终为 0 尝试使用e.which 它的 null 这些都不起作用 【参考方案1】:

这是来自 Android 触摸键盘实现的 deliberate decision。

唯一的解决方法是处理实际的输入文本:

inputElement.addEventListener('beforeinput', e => 
    if(e.inputType === 'deleteContentBackward') 
        // check whatever you want to check for
        if(!myCondition(e))
            e.preventDefault() // will block the deletion
    
)

【讨论】:

你能给我举个例子吗,在我的情况下,我只需要控制退格键,根据我在 beforeInput 事件中尝试的某些条件阻止用户删除字符,但它并没有阻止用户删除字符? 如果新文本不符合你的条件,你可以观察输入变化和e.preventDefault() 你能给我一些示例代码吗?我的意思是我应该创建一个观察者还是有任何可以取消的事件? 在事件中,从输入中读取文本。缓存它。首先将当前文本与缓存进行比较,并得出有效的按键(我假设您主要关心新输入,而不是删除)。文本替换可能会检测到更改未命中,但可以轻松捕获(可能重置并扫描您的有效按键)。这就是我对它的阅读,基于该链接 我只需要防止删除,不关心新的输入,只想在安卓手机上禁用退格键【参考方案2】:

如果它是 react-native 那么我们可以扩展 webivew 库并覆盖 onCreateInputConnection 方法。对于任何想要扩展 webview 的人,这里是代码

    首先创建CustomWebviewManager.java文件并添加内容

打包你的包名;

import com.reactnativecommunity.webview.RNCWebViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.InputConnectionWrapper;
import com.facebook.react.module.annotations.ReactModule;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.os.Build;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.javascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.CookieManager;


@ReactModule(name = CustomWebViewManager.REACT_CLASS)
public class CustomWebViewManager extends RNCWebViewManager 
  /* This name must match what we’re referring to in JS */
  protected static final String REACT_CLASS = “MyCustomWebView”;

  protected static class CustomWebViewClient extends RNCWebViewManager.RNCWebViewClient  

  protected static class CustomWebView extends RNCWebViewManager.RNCWebView  
    public CustomWebView(ThemedReactContext reactContext) 
      super(reactContext);
    
    
    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs)    
        return new BaseInputConnection(this, false);
    
  

  

  @Override
  protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) 
    return new CustomWebView(reactContext);
  

  @Override
  public String getName() 
    return REACT_CLASS;
  



  @Override
  protected void addEventEmitters(ThemedReactContext reactContext, WebView view) 
    view.setWebViewClient(new CustomWebViewClient());
  

    然后创建自己的web视图包文件CustomWebViewPackage.java

     package your-package-name;
     import java.util.Arrays;
     import java.util.Collections;
     import java.util.ArrayList;
     import java.util.List;
     import com.facebook.react.ReactPackage;
     import com.facebook.react.bridge.NativeModule;
     import com.facebook.react.bridge.ReactApplicationContext;
     import com.facebook.react.uimanager.ViewManager;
    
     public class CustomWebViewPackage implements ReactPackage 
         @Override
         public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) 
           return Collections.emptyList();
         
    
         @Override
         public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) 
           return Arrays.<ViewManager>asList(new CustomWebViewManager());
         
     
    

然后在你的 Webivew 组件中像这样加载它

MyCustomWebView = requireNativeComponent(‘MyCustomWebView’, MyNotesEditor,
    WebView.extraNativeComponentConfig);    

 <Webview
     nativeConfig=component: MyCustomWebView
  />

【讨论】:

谢谢!我使用您的评论来捕获并发送回退格键代码。 gist.github.com/dakhipp/72377353da53d9b106d705a0e8c64c81 很高兴它对你有所帮助:)【参考方案3】:

不幸的是,这是react-native-webview 问题

Keyboard event event.key is unidentified #1473

【讨论】:

它不是 react-native-webview 与 android chrome 浏览器有关的问题

以上是关于键盘事件 event.key 在 android webview 上无法识别的主要内容,如果未能解决你的问题,请参考以下文章

鼠标键盘事件对象常用属性

Python事件没有Key属性

如何获得鼠标和键盘的移动? - Python

Android:软键盘不消耗输入事件/触摸

Android 键盘事件触发以及监听

在 Android 中模拟键盘事件