Reputation: 437
In Unity I can't control the touchscreen keyboard. TouchScreenKeyboard class has only one parameters for Android.
if(TouchScreenKeyboard.visible)
{ float keyboardHeight = TouchScreenKeyboard.area.height;
// will resize the view here! But this return zero!
}
Is there any other way to know the height of the keyboard on Android ?
Upvotes: 9
Views: 12940
Reputation: 91
I got this to work relative to the canvas size, here is the code... All you need is to call it with the canvas RectTransform reference.
public static int GetRelativeKeyboardHeight(RectTransform rectTransform, bool includeInput)
{
int keyboardHeight = GetKeyboardHeight(includeInput);
float screenToRectRatio = Screen.height / rectTransform.rect.height;
float keyboardHeightRelativeToRect = keyboardHeight / screenToRectRatio;
return (int) keyboardHeightRelativeToRect;
}
private static int GetKeyboardHeight(bool includeInput)
{
#if UNITY_EDITOR
return 0;
#elif UNITY_ANDROID
using (AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
AndroidJavaObject view = unityPlayer.Call<AndroidJavaObject>("getView");
AndroidJavaObject dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
if (view == null || dialog == null)
return 0;
var decorHeight = 0;
if (includeInput)
{
AndroidJavaObject decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
if (decorView != null)
decorHeight = decorView.Call<int>("getHeight");
}
using (AndroidJavaObject rect = new AndroidJavaObject("android.graphics.Rect"))
{
view.Call("getWindowVisibleDisplayFrame", rect);
return Screen.height - rect.Call<int>("height") + decorHeight;
}
}
#elif UNITY_IOS
return (int)TouchScreenKeyboard.area.height;
#endif
}
Upvotes: 0
Reputation: 1898
It was long ago, but just in case anybody is struggling with it again, I managed to find a solution for a panel with an InputField using this MonoBehaviour class. I attached it to the InputField and linked the panel which should be resized.
public class InputFieldForScreenKeyboardPanelAdjuster : MonoBehaviour {
// Assign panel here in order to adjust its height when TouchScreenKeyboard is shown
public GameObject panel;
private InputField inputField;
private RectTransform panelRectTrans;
private Vector2 panelOffsetMinOriginal;
private float panelHeightOriginal;
private float currentKeyboardHeightRatio;
public void Start() {
inputField = transform.GetComponent<InputField>();
panelRectTrans = panel.GetComponent<RectTransform>();
panelOffsetMinOriginal = panelRectTrans.offsetMin;
panelHeightOriginal = panelRectTrans.rect.height;
}
public void LateUpdate () {
if (inputField.isFocused) {
float newKeyboardHeightRatio = GetKeyboardHeightRatio();
if (currentKeyboardHeightRatio != newKeyboardHeightRatio) {
Debug.Log("InputFieldForScreenKeyboardPanelAdjuster: Adjust to keyboard height ratio: " + newKeyboardHeightRatio);
currentKeyboardHeightRatio = newKeyboardHeightRatio;
panelRectTrans.offsetMin = new Vector2(panelOffsetMinOriginal.x, panelHeightOriginal * currentKeyboardHeightRatio);
}
} else if (currentKeyboardHeightRatio != 0f) {
if (panelRectTrans.offsetMin != panelOffsetMinOriginal) {
SmartCoroutine.DelayedExecute(this, () => {
Debug.Log("InputFieldForScreenKeyboardPanelAdjuster: Revert to original");
panelRectTrans.offsetMin = panelOffsetMinOriginal;
}, 0.5f);
}
currentKeyboardHeightRatio = 0f;
}
}
private float GetKeyboardHeightRatio() {
if (Application.isEditor) {
return 0.4f; // fake TouchScreenKeyboard height ratio for debug in editor
}
#if UNITY_ANDROID
using (AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
using (AndroidJavaObject rect = new AndroidJavaObject("android.graphics.Rect")) {
View.Call("getWindowVisibleDisplayFrame", rect);
return (float)(Screen.height - rect.Call<int>("height")) / Screen.height;
}
}
#else
return (float)TouchScreenKeyboard.area.height / Screen.height;
#endif
}
}
Upvotes: 3
Reputation: 2720
This should do the trick (found here):
public int GetKeyboardSize()
{
using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
using(AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
{
View.Call("getWindowVisibleDisplayFrame", Rct);
return Screen.height - Rct.Call<int>("height");
}
}
}
Upvotes: 8