Unity适配 安卓15+三键导航模式下的 底部UI被遮挡

在发布android15以上的apk,如果手机采用的经典导航键,那么底部的按钮将会被安全区域遮挡。

解决这个问题,有两种思路。

1.打开全屏模式

cs 复制代码
private void FullScreen()
{
    // 强制设置全屏
    Screen.fullScreen = true;
    // 使用沉浸模式,隐藏底部的虚拟按键
    Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen;
}

全屏下,导航栏会默认消失,但是你从底部下往上滑动的时候,导航栏会出现,一会后会自动消失

2.获取安全区域的高度,让UI的位置+安全区域的高度

cs 复制代码
    private RectTransform rt;
    private Canvas canvas;

    private void ApplySafeOffset()
    {

        rt = GetComponent<RectTransform>();
        canvas = GetComponentInParent<Canvas>();
        if (rt == null || canvas == null) return;

        float bottomPixelHeight = 0;

        // 首先尝试原生接口 
        if (Application.platform == RuntimePlatform.Android)
        {
            bottomPixelHeight = GetAndroidBottomInset();
            if (bottomPixelHeight > 0)
                Debug.Log($"[SafeAreaAdapter] 从 Android 底层获取到避让高度: {bottomPixelHeight}");
        }
        else
            return;

     
        if (bottomPixelHeight > 0)
        {
            float scaleFactor = canvas.scaleFactor;
            float offsetInCanvas = bottomPixelHeight / scaleFactor;

            Vector2 newPos = rt.anchoredPosition;
            newPos.y = offsetInCanvas; // 直接设置为偏移量,避免重复累加
            rt.anchoredPosition = newPos;
            Debug.Log($"[SafeAreaAdapter] 适配成功: {offsetInCanvas} Canvas单位");
        }
        else
        {
            Debug.Log("[SafeAreaAdapter] 所有检测均返回0,可能是全屏手势模式。");
        }
    }

    // 调用 Android 原生 API 获取真正的底部高度
    private float GetAndroidBottomInset()
    {
        try
        {
            using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
            using (var window = activity.Call<AndroidJavaObject>("getWindow"))
            using (var decorView = window.Call<AndroidJavaObject>("getDecorView"))
            using (var rootInsets = decorView.Call<AndroidJavaObject>("getRootWindowInsets"))
            {
                if (rootInsets != null)
                {
                    // 获取系统窗口插入高度 (包括导航栏)
                    return rootInsets.Call<int>("getSystemWindowInsetBottom");
                }
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("[SafeAreaAdapter] 获取原生 Insets 出错: " + e.Message);
        }
        return 0;
    }

这里增加一个判断,要大于35的才能去抬高,因为在android15之前,是不用抬起的,这里不加判断设置android版本的话,只要有安全区域就会抬起,是有问题

复制代码
    public int GetAndroidSDKVersion()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
    using (var version = new AndroidJavaClass("android.os.Build$VERSION"))
    {
        // Android 15 对应的 SDK_INT 是 35
        return version.GetStatic<int>("SDK_INT");
    }
#endif
        return -1;
    }
相关推荐
大貔貅喝啤酒12 小时前
基于Windows下载安装Android Studio 3.3.2版本教程(2026详细图文版)
android·java·windows·android studio
程序员码歌12 小时前
OpenSpec 到 Superpowers:AI 编码从说清到做对
android·前端·人工智能
2501_9151063212 小时前
深入解析无源码iOS加固原理与方案,保护应用安全
android·安全·ios·小程序·uni-app·cocoa·iphone
蒂法就是我14 小时前
CAD专业看图师手机版安装使用教程
智能手机·cad看图
黄林晴16 小时前
重磅官宣:Android UI 开发正式进入 Compose-first 时代
android·google io
Kapaseker16 小时前
搞懂变换!精通 Compose 绘制(二)
android·kotlin
美狐美颜SDK开放平台16 小时前
美颜SDK开发详解:如何优化美颜SDK在低端安卓机上的性能?
android·ios·音视频·直播美颜sdk·视频美颜sdk
Gary Studio16 小时前
深入MTK Android BSP:如何确定编译目标与查找项目设备树
android
casual_clover16 小时前
【Android】实现状态栏背景透明,系统时间/图标直接显示在页面背景上
android·透明状态栏
blackorbird16 小时前
Android Pixel 10 零点击漏洞利用链
android