前言
1>聊天软件中,虚拟键盘弹起会盖住聊天窗口,将整个聊天界面上移
2>unity游戏中, 虚拟键盘弹起会盖住输入框,将输入框 上移(不能跟聊天软件一样处理)
这章讲述 游戏解决方案
1 环境
unity2020
2 布局
3 脚本
SampleScene.cs
拖到Main Camera 上 再把InputField 拖到脚本变量里
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SampleScene : MonoBehaviour
{
public InputField inputField;
Canvas canvas;
ChatViewAdaptMobileKeyBoard chatview;
GameObject canvasobject;
// Start is called before the first frame update
void Start()
{
Debug.LogError("SampleScene Start 1");
canvas = (Canvas) GameObject.FindObjectOfType(typeof(Canvas));
if(canvas == null)
{
Debug.LogError("SampleScene Start error");
}
canvasobject = canvas.gameObject;
Debug.LogError("SampleScene Start 3");
chatview = ChatViewAdaptMobileKeyBoard.Create(canvasobject, inputField);
Debug.LogError("SampleScene Start 4");
}
// Update is called once per frame
void Update()
{
}
}
ChatViewAdaptMobileKeyBoard.cs
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 移动设备输入框的自适应组件
/// </summary>
public class ChatViewAdaptMobileKeyBoard : MonoBehaviour {
public InputField _inputField;
// static ChatViewAdaptMobileKeyBoard instance = null;
/// <summary>
/// 自适应(弹出输入框后整体抬高)的面板的初始位置
/// </summary>
private Vector2 _adaptPanelOriginPos;
private RectTransform _adaptPanelRt;
private float RESOULUTION_HEIGHT = 0 ;;//1080F; //1280F;
private float lastkeyboardHeight = 0.00f;
private float rtx = 0;
private float rty = 0;
public static ChatViewAdaptMobileKeyBoard Create(GameObject attachRoot, InputField inputField) {
ChatViewAdaptMobileKeyBoard instance = null;
instance = attachRoot.AddComponent<ChatViewAdaptMobileKeyBoard>();
instance._inputField = inputField;
return instance;
}
private void Start() {
RESOULUTION_HEIGHT = Display.main.systemHeight ; //屏幕高
Debug.LogError("检测到InputField ChatViewAdaptMobileKeyBoard.start()");
_inputField.onEndEdit.AddListener(OnEndEdit);
_inputField.onValueChanged.AddListener(OnValueChanged);
// _adaptPanelRt = transform.Find("TabControl/Panels").GetComponent<RectTransform>();
// _adaptPanelRt = transform.Find("Canvas/InputField").GetComponent<RectTransform>();
_adaptPanelRt = this._inputField.GetComponent<RectTransform>();//相对于父对象的位置(没有父对象就根据世界原点)
// rtx = _adaptPanelRt.
_adaptPanelOriginPos = _adaptPanelRt.anchoredPosition; //自身中心点相对于锚点之间的位置
rtx = _adaptPanelOriginPos.x;
rty = _adaptPanelOriginPos.y;
Debug.LogError("检测到InputField inputfield org x =" + _adaptPanelOriginPos.x.ToString() + " y="+ _adaptPanelOriginPos.y.ToString());
}
private void Update() {
if (_inputField.isFocused) {
if (Application.platform == RuntimePlatform.Android) {
float keyboardHeight = (int)(AndroidGetKeyboardHeight()*RESOULUTION_HEIGHT)/Screen.height;
if (keyboardHeight - lastkeyboardHeight < 1.1f || keyboardHeight - lastkeyboardHeight < -1.1f)
{
}
else
{
lastkeyboardHeight = keyboardHeight;
// Debug.LogFormat("安卓平台检测到InputField.isFocused为真,获取键盘高度:{0}, Screen.height:{1}", keyboardHeight, Screen.height);
//2340 × 1080像素 mate30
// Debug.LogError("安卓平台检测到InputField.isFocused为真,获取键盘高度:"+ keyboardHeight.ToString()+" Screen.height:"+ Screen.height.ToString());
//_adaptPanelRt.anchoredPosition = Vector3.up * (keyboardHeight);
// _adaptPanelRt.anchoredPosition = _adaptPanelOriginPos.Set(_adaptPanelOriginPos.x,_adaptPanelOriginPos.y);
_adaptPanelRt.anchoredPosition = new Vector2(rtx, rty + keyboardHeight);// +150f);//150 输入法的输入框 高度(估计的)//勾选 hide mobile intput 不需要额外增加150
_adaptPanelRt.ForceUpdateRectTransforms(); //强制更新
Debug.LogError("安卓平台检测到InputField.isFocused为真,获取键盘高度:" + keyboardHeight.ToString() + " Screen.height:" + Screen.height.ToString() + " anchposy=" + _adaptPanelRt.anchoredPosition.y.ToString());
}
}
else if (Application.platform == RuntimePlatform.IPhonePlayer) {
float keyboardHeight = IOSGetKeyboardHeight() * RESOULUTION_HEIGHT / Screen.height;
// Debuger.LogFormat("IOS平台检测到键盘高度:{0},Screen.height: {1}", keyboardHeight, Screen.height);
_adaptPanelRt.anchoredPosition = Vector3.up * keyboardHeight;
}
else {
//Editor或其他平台,测试用!
// _adaptPanelRt.anchoredPosition = Vector3.up * 300f;
// _adaptPanelRt.anchoredPosition = Vector2.up * 300f;
Debug.LogError("安卓平台检测到InputField.isFocused为真,获取键盘高度 other 提升300f");
_adaptPanelRt.anchoredPosition = new Vector2(rtx, rty + 300f); //.Set(rtx, rty + 300f);
}
}else
{
if (Application.platform == RuntimePlatform.Android)
{
if ((int)_adaptPanelRt.anchoredPosition.y -(int)rty < 1.1f || (int)_adaptPanelRt.anchoredPosition.y - (int)rty < -1.1f)
{
}
else
{
Debug.LogError("安卓平台检测到InputField.isFocused为假,获取键盘高度 y=" + rty.ToString());
// _adaptPanelRt.anchoredPosition = _adaptPanelOriginPos; //自身中心点相对于锚点之间的位置
_adaptPanelRt.anchoredPosition = new Vector2(rtx, rty);
}
}
}
}
private void OnValueChanged(string arg0) { }
/// <summary>
/// 结束编辑事件,TouchScreenKeyboard.isFocused为false的时候
/// </summary>
/// <param name="currentInputString"></param>
private void OnEndEdit(string currentInputString) {
//Debuger.LogFormat("OnEndEdit, 输入内容:{0}, 结束时间:{1}", currentInputString, Time.realtimeSinceStartup);
// _adaptPanelRt.anchoredPosition = _adaptPanelOriginPos;
Debug.LogError("安卓平台检测到InputField.isFocused 结束,获取键盘高度 y=" + rty.ToString());
// _adaptPanelRt.anchoredPosition.Set(rtx, rty);
_adaptPanelRt.anchoredPosition = new Vector2(rtx, rty);
lastkeyboardHeight = 0.0f;
_adaptPanelRt.ForceUpdateRectTransforms(); //强制更新
}
/// <summary>
/// 获取安卓平台上键盘的高度
/// </summary>
/// <returns></returns>
public int AndroidGetKeyboardHeight() {
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");
}
}
}
public float IOSGetKeyboardHeight() {
return TouchScreenKeyboard.area.height;
}
}
4 运行结果
注意 inputfield hidemobileinput 勾选 不然 会多出个输入框
5 后续如需可以上传DEMO工程