using UnityEngine; using UnityEngine.UI; namespace Kill.UI.Components { /// /// autofill 语义类型(对应 Android autofillHints) /// public enum AutofillHint { EmailAddress, // emailAddress Username, // username Password, // password } /// /// 隐形原生输入桥(Android 谷歌密码自动填充) /// /// 用法:AutofillBridge.Attach(inputField, AutofillHint.Password) /// Attach 后会在 InputField 上叠一层透明按钮拦截点击:点击不再激活 Unity 自带键盘, /// 而是在 InputField 的屏幕位置弹出带 autofillHints 的隐形原生 EditText, /// 由谷歌密码管理器提供填充建议;输入内容实时同步回 Unity InputField 显示。 /// 登录成功时调用 Commit() 触发"保存密码"提示。 /// public static class AutofillBridge { private const string JavaClass = "com.photonmatrix.autofill.AutofillBridge"; private const string ReceiverGoName = "AutofillBridgeReceiver"; private static AndroidJavaClass sJava; private static GameObject sReceiverGo; private static InputField sActiveField; /// 密码页配套的账号(保存凭据时账号密码成对) public static string CompanionUsername { get; set; } = ""; public static bool Supported => !Application.isEditor && Application.platform == RuntimePlatform.Android; /// /// 绑定 InputField:叠加透明按钮拦截点击,改由原生输入桥承接 /// public static void Attach(InputField field, AutofillHint hint) { if (field == null || !Supported) return; EnsureReceiver(); var blockerGo = new GameObject(field.name + "_AutofillBlocker", typeof(RectTransform), typeof(Image), typeof(Button)); var blockerRt = blockerGo.GetComponent(); var fieldRt = field.transform as RectTransform; blockerRt.SetParent(fieldRt.parent, false); // 复制 InputField 的布局,完全重合 blockerRt.anchorMin = fieldRt.anchorMin; blockerRt.anchorMax = fieldRt.anchorMax; blockerRt.pivot = fieldRt.pivot; blockerRt.anchoredPosition = fieldRt.anchoredPosition; blockerRt.sizeDelta = fieldRt.sizeDelta; blockerRt.localScale = Vector3.one; blockerRt.SetAsLastSibling(); // 保持在 InputField 之上,优先接收点击 var img = blockerGo.GetComponent(); img.color = new Color(0, 0, 0, 0); // 全透明,仅用于接收射线 var btn = blockerGo.GetComponent