-
-
Save zeh/f0462204dd6c08cb9821 to your computer and use it in GitHub Desktop.
// On Android, every Activity can respond differently to the software keyboard: scrolling to fit, just resizing, overlaying, etc. | |
// http://developer.android.com/training/keyboard-input/visibility.html | |
// The C# code below adjusts Unity's current Android Activity to make the keyboard overlay the game, with no size adjustments. | |
// It is equivalent to calling getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) in Java. | |
// Helped method needed for proper UI thread calls (required when accessing context views) | |
private static void runOnAndroidUiThread(Action target) { | |
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { | |
using (var activity = unityPlayer.GetStatic("currentActivity")) { | |
activity.Call("runOnUiThread", new AndroidJavaRunnable(target)); | |
} | |
} | |
} | |
// Wrap it | |
private static void setSoftInputModeOverlay() { | |
runOnAndroidUiThread(setSoftInputModeOverlayInThread); | |
} | |
// Actual logic | |
private static void setSoftInputModeOverlayInThread() { | |
int SOFT_INPUT_ADJUST_NOTHING = 0x00000030; // WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING | |
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { | |
using (var activity = unityPlayer.GetStatic("currentActivity")) { | |
using (var window = activity.Call("getWindow")) { | |
window.Call("setSoftInputMode", SOFT_INPUT_ADJUST_NOTHING); | |
} | |
} | |
} | |
} | |
// Finally, call it | |
setSoftInputModeOverlay(); |
Thanks man. You're right - Unity 5 forces those generic types. Forgot about those.
I'll test out alternatives when I have access to Unity later today.
To answer the question.. I haven't tried manifest editing recently. I know one alternative is exporting it as a project (rather than an apk), editing the project, and recompiling. But it's really really cumbersome and I'm not 100% it still works with Unity 5.
Ah, I think I understand the problem better now.
When you said it was resizing, I assumed the whole game canvas was resizing to fit the smaller area provided by the keyboard. That's what the code snippet (instructing it to overlay) was set to fix. But when I tested it seemed to be fine:
But now that I've played around with it, I believe I misunderstood you. I think I know what you mean: when you hide the navigation completely, AND open the keyboard, it does force a small resize.
It works like this: when the software keyboard is shown, the navigation bar is always enforced. It is used to close the keyboard, I suppose. But it also means that if the navigation bar is set to "invisible", then instead of just showing it above the contenbt, it forces it to completely visible, thus resizing.
There's two ways to fix it.
- Set the navigation bar to "translucent over content" or "visible over content" instead. This makes the keyboard display without resizing. When the keyboard closes, you need to set it to invisible again.
Or
- Naturally listen to events and circumvent the system to always reset that flag. Haven't done this yet, but there's a discussion about this here at StackOverflow.
Let me see if there's a quick/easy fix that makes sense to add to this library.
Edit: nevermind that. I finally got it the way I originally thought you described. It's the full software resize. Sorry about the misunderstanding. Let me investigate it.
I tested virtually the same thing (inferring from your ApplicationChrome class) to no avail with the call:
window.Call("setSoftInputMode", 0x00000030);
I figured I may have implemented it wrong and just tried your sample above. I had to update two things due to errors from:
...
using (var activity = unityPlayer.GetStatic("currentActivity")) {
using (var window = activity.Call("getWindow")) {
...
to
...
using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
using (var window = activity.Call<AndroidJavaObject>("getWindow")) {
...
Unfortunately, it still doesn't work. If I don't use the call
ApplicationChrome.statusBarState = ApplicationChrome.States.Visible;
, then the soft keyboard simply overlays the game screen as desired. However if I make that call, then the keyboard forces the rest of the window to resize as opposed to overlaying. Any other thoughts? Or can you confirm on your end when you have access to Unity?As a side, do you know how edit the
AndroidManifest.xml
in Unity 5.0+? It seems like theAndroidManifest.xml
is more of a black box in Unity 5.0+.