如何在Android上使用Unity时,当触摸键盘可见时调整视图大小?

9
在Unity中,我无法控制触摸屏键盘。TouchScreenKeyboard类在安卓平台上只有一个参数。
if(TouchScreenKeyboard.visible)
{ float keyboardHeight = TouchScreenKeyboard.area.height;
  // will resize the view here! But this return zero!
}

有没有其他方法可以知道 Android 键盘的高度?

修正了拼写错误!你对这个问题有什么想法吗? - Çağatay Kaya
我找到了这个:http://forum.unity3d.com/threads/keyboard-height.291038/ - Jerry Switalski
3个回答

8
这里有一个可行的方法(在这里找到):
    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");
            }
        }
    }

非常感谢,我会尽快尝试并回复结果。 :D - Çağatay Kaya

3

虽然时间已经很久了,但如果有人再次遇到以下问题,我找到了一个解决方案。我们可以使用这个MonoBehaviour类来调整带有InputField的面板大小。将其附加到InputField上,并链接要调整大小的面板即可。

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
    }

}

非常好,谢谢。只需将“SmartCoroutine.DelayedExecute”替换为您的内部库即可。 - Martin Asenov
对于SmartCoroutine,@Vitaliy使用它来延迟重置的操作可以通过将其内容移动到另一个方法中,并在所需的延迟后调用该方法来实现。 } else if (ratio != 0f) { if (panelRectTrans.offsetMin != panelOffsetMinOriginal) Invoke("DelayedReset", 0.5f); ratio = 0f; } void DelayedReset() { Debug.Log("InputFieldForScreenKeyboardPanelAdjuster: 恢复原始状态"); panelRectTrans.offsetMin = panelOffsetMinOriginal; } - olonge
需要修复iPhone 11的问题,因为此解决方案无法将输入字段容器完全向上移动。键盘覆盖了大约一半的输入字段。 - Valerie
我通过使用Screen.safeArea.height来修复了iPhone 11的问题。例如,返回(float)TouchScreenKeyboard.area.height / Screen.safeArea.height; - Valerie
虽然有点老了,但我觉得这个很有用,想分享一下我们的更新,结合了olonge和Valerie的建议,还进行了一些清理,并支持限制重置,如果在同一个目标容器(即面板)上发现了其他用途。此外,还支持使用anchorPosition3D,如果父容器位于视图中心,则效果更好。https://github.com/playvue/UnityHelpers/blob/master/Scripts/InputFieldForScreenKeyboard.cs - kfblake

0

我已经让它相对于画布大小工作了,这是代码...你只需要使用画布RectTransform引用调用它。

    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
    }

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