当前位置: 首页 > news >正文

专业的高端企业网站一起看在线观看免费

专业的高端企业网站,一起看在线观看免费,网页源码下载,html5优秀企业网站在 Android 中判定底部导航栏是否显示时,核心痛点是 区分 “导航栏的底部 Insets” 和 “软键盘弹出的底部 Insets”—— 两者都会导致 getSystemWindowInsetBottom() 返回非零值,直接判断会误将键盘弹出当成导航栏显示。以下是基于 WindowInsets 类型区…

在 Android 中判定底部导航栏是否显示时,核心痛点是 区分 “导航栏的底部 Insets” 和 “软键盘弹出的底部 Insets”—— 两者都会导致 getSystemWindowInsetBottom() 返回非零值,直接判断会误将键盘弹出当成导航栏显示。以下是基于 WindowInsets 类型区分 的精准解决方案,兼容不同 Android 版本和场景。

核心原理:通过 Insets 类型过滤键盘

Android 的 WindowInsets 会标记不同来源的 “插入区域”(如导航栏、状态栏、软键盘),通过 WindowInsetsCompat.Type 可精准过滤出 仅由导航栏贡献的底部 Insets,从而排除键盘干扰。

关键类型说明:

Insets 类型含义需排除 / 保留
Type.NAVIGATION_BARS系统导航栏(底部 / 侧边)保留(目标判断对象)
Type.IME软键盘(Input Method Editor)排除(干扰项)
Type.STATUS_BARS状态栏(顶部)排除(与底部无关)

方案实现:兼容高低版本的工具类

以下工具类支持 Android 14(API 34)及以下版本,通过 WindowInsetsCompat 统一处理 Insets 类型,精准判断导航栏可见性并获取高度。

import android.view.View;
import androidx.core.view.WindowInsetsCompat;/*** 精准判断底部导航栏是否显示(排除软键盘干扰)*/
public class NavigationBarChecker {/*** 判定底部导航栏当前是否可见(排除键盘)* @param rootView 页面根布局(如 Activity 的 contentView、Fragment 的根View)* @return true:导航栏显示;false:导航栏隐藏或当前是键盘弹出*/public static boolean isNavigationBarVisible(View rootView) {if (rootView == null) {return false;}// 1. 获取根View的WindowInsets(包含所有插入区域信息)WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(rootView);if (insetsCompat == null) {return false; // 极端情况(如View未附着到窗口),返回隐藏}// 2. 关键:仅获取“导航栏”贡献的底部Insets(排除键盘、状态栏等)// Type.NAVIGATION_BARS:指定只计算导航栏的Insetsint navBarBottomInset = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;// 3. 底部Insets > 0 说明导航栏在底部显示(若为侧边导航栏,bottom会是0,需额外判断left/right)return navBarBottomInset > 0;}/*** 获取底部导航栏的真实高度(排除键盘干扰)* @param rootView 页面根布局* @return 导航栏高度(px);0:导航栏隐藏*/public static int getNavigationBarHeight(View rootView) {if (rootView == null) {return 0;}WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(rootView);if (insetsCompat == null) {return 0;}// 同样只取导航栏的底部Insets,即为导航栏高度return insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;}/*** (扩展)判断是否为软键盘弹出状态(辅助验证)* @param rootView 页面根布局* @return true:键盘显示;false:键盘隐藏*/public static boolean isKeyboardVisible(View rootView) {if (rootView == null) {return false;}WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(rootView);if (insetsCompat == null) {return false;}// 仅判断“键盘”贡献的底部Insets:>0 说明键盘弹出//对core 版本有要求,太低找不到//dependencies {//implementation 'androidx.core:core:1.5.0'//}int keyboardBottomInset = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()).bottom;return keyboardBottomInset > 0;}
}

关键细节说明

1. 为什么必须用 ViewCompat.getRootWindowInsets()
  • 避免直接调用 rootView.getRootWindowInsets():该方法在 API 23(Android 6.0)以上才可用,ViewCompat 会自动兼容低版本(API 14+),无需额外版本判断。
  • 确保获取的是 “根 View 的 Insets”:只有根布局(如 setContentView 传入的 View)能拿到完整的系统 Insets,子 View 可能因布局嵌套导致 Insets 被截断。
2. 如何处理 “侧边导航栏”(如平板横屏)?

部分设备(平板、折叠屏)在横屏时会将导航栏放在左侧 / 右侧,此时 bottom Insets 为 0,需额外判断 left 或 right

// 扩展:判断任意位置的导航栏是否可见(含侧边)
public static boolean isAnyNavigationBarVisible(View rootView) {if (rootView == null) return false;WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(rootView);if (insetsCompat == null) return false;WindowInsetsCompat.Insets navInsets = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars());// 左/右/下 任意一个方向有Insets,说明导航栏可见return navInsets.left > 0 || navInsets.right > 0 || navInsets.bottom > 0;
}
3. 兼容 Android 14(API 34)的新变化

Android 14 新增了 WindowInsets.Type.systemBars()(包含状态栏 + 导航栏),但 Type.navigationBars() 仍完全兼容,无需修改代码 ——WindowInsetsCompat 已内部适配新 API,保证低版本行为一致。

使用示例(在 Activity 中)

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取页面根布局(必须是setContentView的根View)View rootView = findViewById(android.R.id.content); // 通用获取根View的方式// 1. 监听导航栏可见性变化(如键盘弹出/收起、旋转屏幕时)ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {// 判断导航栏是否显示(排除键盘)boolean isNavVisible = NavigationBarChecker.isNavigationBarVisible(rootView);// 获取导航栏高度int navHeight = NavigationBarChecker.getNavigationBarHeight(rootView);// 判断键盘是否显示(辅助)boolean isKeyboard = NavigationBarChecker.isKeyboardVisible(rootView);// 业务逻辑:如更新UI、调整布局Log.d("NavChecker", "导航栏可见:" + isNavVisible + ",高度:" + navHeight + "px,键盘可见:" + isKeyboard);return insets; // 必须返回Insets,否则后续监听会失效});// 2. 主动触发一次判断(如页面初始化时)boolean initNavVisible = NavigationBarChecker.isNavigationBarVisible(rootView);int initNavHeight = NavigationBarChecker.getNavigationBarHeight(rootView);}
}

常见问题排查

  1. 返回值始终为 0?

    • 检查 rootView 是否为页面根布局(如用 findViewById(android.R.id.content) 替代子 View)。
    • 确保布局未设置 fitsSystemWindows="true":该属性会让 View 消费 Insets,导致 getInsets() 返回 0(如需使用,需在根 View 的父布局设置)。
  2. 键盘弹出时误判为导航栏?

    • 确认代码中使用 WindowInsetsCompat.Type.navigationBars() 而非 Type.systemBars() 或直接 getSystemWindowInsetBottom()—— 后者会包含键盘 Insets。
  3. 低版本(API < 21)不生效?

    • Android 5.0(API 21)以下无官方 Insets API,若需兼容,可通过 反射获取系统资源 间接判断(但精度较低,建议最低兼容到 API 21):
      // 兼容API < 21:通过系统资源判断导航栏是否存在(无法实时判断显示/隐藏)
      public static boolean hasNavigationBar(Context context) {Resources res = context.getResources();int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");if (resourceId > 0) {return res.getBoolean(resourceId);}return false; // 无法判断时默认返回false
      }
      
http://www.dtcms.com/a/615244.html

相关文章:

  • 【Git】2025全图文详解安装教程
  • 松江手机网站开发南阳网站推广排名
  • 关于网站设计的书籍哈尔滨网站制作软件
  • 好用的wordpress谷歌推广优化
  • 玄武网站制作收费报价东莞房产网
  • 九州建网站厦门seo排名公司
  • 浦江县建设局网站网站模板如何修改
  • 解码IPC-消息队列、共享内存与信号量集
  • 【MicroPython编程-ESP32篇】-WS2812B全彩LED驱动
  • 娱乐网站建设公司wordpress伪静态 page
  • 技术支持 上海做网站wordpress 文章 批量 分类
  • 惠州做网站的公司有哪些中建国际建设有限公司官网是央企吗
  • 一步一步学习使用LiveBindings() 实现对JSON数据的绑定
  • 优秀网站赏析网站开发属于专利吗
  • 网站任务界面郑州网站制作开发
  • dede网站版权信息修改平面设计师参考网站
  • 30岁转行做网站设计免费手机看电影app哪个软件好
  • 视频网站源码下载免费下载logo素材
  • 怎么学好网站开发wordpress oa插件下载
  • AI理论知识系统复习(6):梯度饱和、梯度消失、梯度爆炸
  • 昆明微网站搭建哪家好廊坊企业官网搭建
  • 吉林住房和城乡建设厅网站网站设计与规划
  • QT c++ 的数据类型有哪些?
  • Langchain4j笔记+总结 2
  • 深入浅出聊聊synchronized
  • 网站蜘蛛爬行赣州快车公众号
  • 深入理解Python模块和第三方库使用与管理
  • 郑州网站建设的软件奉贤高端网站建设
  • 【架构】安全(二)
  • 设置一个好的网站导航栏网站多久才会被收录