ionic-team / ionic-plugin-keyboard

Ionic Keyboard Plugin for Cordova
Apache License 2.0
610 stars 275 forks source link

Keyboard not behaving consistently on input focus #235

Open ghost opened 7 years ago

ghost commented 7 years ago

I have a major problem with the native.keyboardshow events not firing when a text input is focussed on Android. It seems to work fine on Sumsung devices, but not on stock Android ROMS. It is causing big problems, since it creates a very inconsistent user experience. Sometimes it fires, but sometimes only the focus event fires, but not the keyboard show event. Even if the keyboard is shown.

Any ideas? This is happening on Android only.

markshust commented 7 years ago

I'm experiencing the same issue. How are you implementing the code? I think this may have something to do with adding event listeners to not a global level (ex. inside a component instead of a global level store event). Any thoughts?

ghost commented 7 years ago

Our problem was that our app was running full-screen on Android; full screen mode causes the code inside of Cordova to fail as it looks like there's a watch on the screen size. The events are fired when the screen size changes, but when running full-screen, the sizes mismatch sometimes and the events don't seem to fire. That's my speculation. Are you running fullscreen?

c00 commented 7 years ago

I'm having similar issues on hide. When hiding the soft keyboard about 20% of the time, the hide event doesn't fire. I'm also in fullscreen mode.

I've done some debugging in android studio and I'm noticing that the resultBottom variable isn't accurate. The onGlobalLayoutListener gets fired every time, but sometimes rootView.getWindowVisibleDisplayFrame(r) results in an r.bottom that is the old value rather than the new value. In my case, the height is either 736 with the keyboard down and 246 with the keyboard up. However sometimes, rootView.getWindowVisibleDisplayFrame(r) will show an r.bottom of 736 when dismissing the keyboard, or a 246 when getting the keyboard. This would make the difference 0 and so neither the shown or hidden events are triggered.

My assumption is this probably has to do with the keyboard we're using. If the keyboard app takes a bit longer to be fully loaded and shown, then the screen is still its old height when we're calling rootView.getWindowVisibleDisplayFrame(r).

Is the author of the plugin still actively maintaining it?

c00 commented 7 years ago

A really really dirty workaround that you should never use but seems to be working for me so far is this: in IonicKeybaord.java add import android.os.SystemClock; to the list of Imports at the top. Then add SystemClock.sleep(300); as the first line in the onGlobalLayout() function.

All this does, is wait 300 milliseconds before doing the check, which seems to usually stop the issue.

Note that this is poorly tested and adding these kinds of wait things to workaround timing issues is really a bad idea in general.

skilltik commented 7 years ago

@c00 @saschwarz I tested this hack but doesn't work.

saschwarz commented 7 years ago

I might be seeing a different issue. If I programmatically set focus to an ion-input and tap it the keyboard appears. Or if I use a regular HTML input <ion-item><input type="text" placeholder="here"/></ion-item> and tap it the keyboard appears.

But using any variation of ion-input:

        <ion-item>
            <ion-label>Test</ion-label>
            <ion-input type="text" placeholder="tap here"></ion-input>
        </ion-item>

I can't get the input to accept focus and, of course, then the keyboard doesn't appear.

I added (focus) and (blur) event logging on ion-input and have confirmed that they are never called when ion-input is tapped. If I programmatically focus the input the focus event is emitted and the blur when I tap/click out of it.

skilltik commented 7 years ago

I know that isn't the best solution, but I solved my problem with this:

    $(document).on('focus click', 'input',  function(e){
        setTimeout(function(){
          if (!cordova.plugins.Keyboard.isVisible) {
            cordova.plugins.Keyboard.show();
            cordova.fireWindowEvent('native.keyboardshow', {'keyboardHeight': +262});
            cordova.plugins.Keyboard.isVisible = true;
          }
        },300);
    });

    $(document).on('focusout', 'input',  function(e){
      setTimeout(function(){
        if (cordova.plugins.Keyboard.isVisible) {
          cordova.plugins.Keyboard.close();
          cordova.fireWindowEvent('native.keyboardhide');
          cordova.plugins.Keyboard.isVisible = false;
        }
      },300);
    });
saschwarz commented 7 years ago

The issue for me was the tablet on which I was testing was old and had an old default browser. I installed crosswalk and everything worked perfectly afterward.