检测Android软键盘的显示/隐藏事件

15

我正在尝试在PhoneGap上检测showKeyboardhidekeyboard事件。为此,在deviceready事件上,我放置了以下代码:

  bindEvents: function() {
    document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
    document.addEventListener("menubutton",app.onMenuKeyPress,false);
    document.addEventListener("backbutton",navigateBack,false);
    document.addEventListener("hidekeyboard", onKeyboardHide, false);
    document.addEventListener("showkeyboard", onKeyboardShow, false);
},

这里触发并正常工作的是backbutton事件,但hidekeyboardshowkeyboard事件从未被触发。

此外,为了检测它,我尝试使用window.onresize事件,在浏览器中可以工作。以下是其代码:

window.onresize = function(){
    var screenHeight = $(window).height();
    alert(screenHeight);
    var diff = screenInitialHeight - screenHeight;
    var newHeight = screenInitialHeight-diff;
    alert(newHeight);
    $('#mainpage').height(newHeight);
    $('#nav_container').height(newHeight);
}

但是这段代码在显示或隐藏键盘时也没有执行。这个函数只在第一次启动应用程序时执行。我在一些地方看到,对于有些人来说这些事件是有效的,所以我认为可能是我这边有些配置文件等方面存在问题。因此,以下是androidmanifest.xml代码:

    <?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="1.0.0" android:windowSoftInputMode="adjustPan" package="com.phonegap.move_custom" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:largeHeap="true">
        <activity android:configChanges="keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="move_custom" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>
请告诉我是否需要进行任何更改。如果这些事件在某个人的应用程序中正常工作,请分享您的应用程序,以便我可以尝试检查配置和代码,以确定为什么它不能在我的应用程序中正常工作。所有良好的尝试都将受到赞赏。似乎我已经接近了解决问题,但还是有所遗漏。因此,您能提供的任何信息可能都会有所帮助。
    @Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    
    if (getResources().getConfiguration().orientation == 2) {
        super.setIntegerProperty("splashscreen", R.drawable.splash);
    }
    else {
        super.setIntegerProperty("splashscreen", R.drawable.splashportrait);
    }
    
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

    super.loadUrl(Config.getStartUrl(), 3000);
}

没有隐藏和显示键盘的事件(http://docs.phonegap.com/en/edge/cordova_events_events.md.html#Events) - Ardavan Kalhori
如果您想检测键盘的状态,您需要编写一个自定义的PhoneGap插件,然后使用Java检测键盘是否弹出或关闭,然后将其传递给JavaScript。 - Ardavan Kalhori
@Ard 那我需要为 iOS 编写类似的插件吗? - Hafiz
@Ard,难道没有已经可用的插件吗? - Hafiz
同时,键盘并没有改变屏幕高度,它只是覆盖在上面。如果它能够改变屏幕高度,那么我就可以相应地检测并采取一些措施。因此,在Android清单中是否有这样的配置,使键盘调整窗口大小而不仅仅是覆盖它? - Hafiz
你确定onKeyboardShowonKeyboardHide函数不会在其他地方损坏你的代码吗?你能把它们添加到你的问题中吗?我刚在Android 4.3上测试了一下,完全没有问题。 - benka
2个回答

15

据报道,当您在全屏模式下运行应用程序(例如,顶部没有状态栏)时,showkeyboard/hidekeyboard事件不会触发,因为键盘弹出时屏幕大小不会改变。
https://issues.apache.org/jira/browse/CB-392

如果您不想让应用程序以全屏模式运行:

首先尝试这个,看看它是否将问题缩小到事件触发或事件触发时它尝试调用的函数上。

function onDeviceReady() {
    alert("Device Ready");
    document.addEventListener("showkeyboard", function(){ alert("Keyboard is ON");}, false);
    document.addEventListener("hidekeyboard", function(){ alert("Keyboard is OFF");}, false);
}

我已在Android 4.2和4.3上测试过,两者都可以正常运行。

注意:

要关闭全屏,请从您的AndroidManifest.xml中删除NoTitleBar

android:theme="@android:style/Theme.Black.NoTitleBar

并且/或者将下列代码添加至MainActivity.javaonCreate方法中:

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

2
这是正确的;全屏在Android上意味着全屏。您的窗口不会因状态栏而缩小,也不会因键盘而缩小。Phonegap依赖于其窗口缩小以便检测键盘的存在,因此该检测在全屏模式下将无法工作。还要注意,尽管绝大多数键盘确实会导致Phonegap窗口在非全屏模式下缩小,但如果用户使用更不寻常的键盘应用程序,则仍可能无法检测到它。这不是您应该依赖的东西。 - j__m
这不显示移动设备的标题栏。已经做了上述两件事情。 - Hafiz
@Hafiz,你使用Phonegap启动画面吗?根据我的经验,它会影响全屏设置。因此,在启动画面显示后,必须设置这些标志以避免全屏。 - benka
已经在启动界面后添加了set。我现在已经把我的onCreate方法的代码添加到问题中,请在那里检查代码。 - Hafiz
将所有的标志内容放在 super.loadUrl(Config.getStartUrl(), 3000); 后面。 - benka

0

使用ionic-plugin-keyboard,即使在全屏/沉浸模式下,也会触发事件native.keyboardshownative.keyboardhide

示例代码:

document.addEventListener('deviceready', 
  function(){
    // disable immersive mode  on Android when keyboard is shown
        try {
      if (cordova.platformId == 'android') {
        AndroidFullScreen.immersiveMode(false, false);
        window.addEventListener('native.keyboardshow', function (e) {
          AndroidFullScreen.showSystemUI(false, false);

        });
        window.addEventListener('native.keyboardhide', function (e) {
          AndroidFullScreen.immersiveMode(false, false);
        });
      }
    } catch (error) {
      console.log('deviceready - ' + error);
    }
}, false);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接