Android中Window和LayoutParams的常用属性及常用方法介绍
Window和LayoutParams的常用属性及常用方法介绍
- Window
- 窗口视图相关
- 窗口动画相关
- 窗口显示相关
- 窗口面板相关
- 窗口背景透明度相关
- 窗口状态栏导航栏相关
- 其他常用方法
- WindowManager.LayoutParams
- 尺寸相关
- 位置偏移相关
- 显示交互相关
- 其他常用方法
- 为什么使用 mWindow.setType() 设置层级不生效?
- Window.setType() 方法的设计局限
- WindowManager.LayoutParams 是系统认可的配置载体
- 结论
Window
Window mWindow = getWindow(); // 获取当前窗口(在 Activity 或 Dialog 中调用)
窗口视图相关
mWindow.getDecorView(); // 获取窗口的根视图 DecorViewmWindow.addContentView(); // 追加一个新视图到窗口的内容视图层级中(与 setContentView() 不同,它不会替换已有的内容视图,而是在已有视图的基础上追加新的视图,追加的视图会被添加到窗口的 DecorView 内部的内容容器中,与原有视图共用同一个窗口层级)mWindow.setContentView(); // 为窗口设置内容视图(会替换窗口中现有的所有内容视图,仅保留新设置的视图)
窗口动画相关
mWindow.setWindowAnimations(); // 设置窗口切换动画(如 Activity 跳转、弹窗显示 / 消失动画)
窗口显示相关
mWindow.setType(); // 设置窗口类型层级mWindow.setLayout(); // 设置窗口的宽高mWindow.setGravity(); // 设置窗口在屏幕中的对齐方式mWindow.setFlags(); // 设置窗口标志(如全屏、悬浮等)mWindow.addFlags(); // 追加窗口标志(与 setFlags 类似,但此方法不会覆盖已有标志)mWindow.clearFlags();// 清除指定的窗口标志
窗口面板相关
mWindow.closePanel(); // 关闭窗口中指定类型的面板(如关闭输入法,针对性关闭单个类型的面板)mWindow.closeAllPanels(); // 关闭当前窗口中所有的面板(包括输入法软键盘、选项菜单、搜索面板、自定义面板等)
窗口背景透明度相关
mWindow.setAlpha(); // 设置窗口整体透明度(0.0 全透明,1.0 不透明)mWindow.setDimAmount(); // 设置窗口背景模糊度(0.0 完全透明,1.0 完全变暗)mWindow.setBackgroundDrawable(); // 设置窗口背景
窗口状态栏导航栏相关
mWindow.setStatusBarColor(); // 设置状态栏颜色mWindow.setNavigationBarColor(); // 设置导航栏颜色
其他常用方法
mWindow.equals(); // 判断两个窗口对象是否为同一个窗口(即检查它们是否指向同一个窗口实例)mWindow.getAttributes(); // 获取窗口的布局参数 LayoutParamsmWindow.setAttributes(); // 将布局参数(WindowManager.LayoutParams)应用到当前窗口(通常与 getAttributes() 配合使用,先通过 getAttributes() 获取当前窗口的参数对象(LayoutParams),再修改该对象的属性(宽高、层级、显示位置、透明度、标志位等),再通过此方法将修改后的参数应用到窗口)mWindow.addOnFrameMetricsAvailableListener(); // 注册一个监听器,用于监听窗口绘制帧的性能指标(如绘制耗时、布局耗时、同步耗时等,帮助分析和优化 UI 渲染性能,尤其是检测掉帧问题)
WindowManager.LayoutParams
WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
尺寸相关
mLayoutParams.width = 100; // 窗口宽度
mLayoutParams.height = 100; // 窗口高度
位置偏移相关
mLayoutParams.gravity = Gravity.CENTER; // 窗口在父容器中的对齐方式mLayoutParams.x = Gravity.CENTER; // 窗口相对于 gravity 对齐位置的偏移量(正值向右、负值向左)
mLayoutParams.y = Gravity.CENTER; // 窗口相对于 gravity 对齐位置的偏移量(正值向下、负值向上)
显示交互相关
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; // 指定窗口的类型(决定窗口层级和系统交互权限)mLayoutParams.flags = FLAG_FULLSCREEN; // 控制窗口的交互、显示特性(可通过 | 组合多个标志,FLAG_FULLSCREEN:全屏显示(隐藏状态栏))mLayoutParams.alpha = 0.0f; // 窗口整体透明度(0.0 全透明~1.0 不透明)mLayoutParams.dimAmount = 0.6f; // 窗口背景变暗程度(0.0 不变暗~1.0 全暗)mLayoutParams.windowAnimations = R.style.Base_DialogWindowTitle_AppCompat; // 窗口切换动画资源 ID(如进出场动画,需在 res/anim 定义)mLayoutParams.softInputMode = SOFT_INPUT_STATE_HIDDEN; // 软键盘交互模式(如 SOFT_INPUT_ADJUST_RESIZE(布局自适应软键盘)、SOFT_INPUT_STATE_HIDDEN(默认隐藏软键盘))
其他常用方法
mLayoutParams.copyFrom(params); // 将 params 的属性复制到当前对象
为什么使用 mWindow.setType() 设置层级不生效?
现象:使用 mWindow.setType() 设置层级不生效,反而使用mLayoutParams.type 然后 mWindow.setAttributes(mLayoutParams) 生效了
分析:核心原因在于 Window.setType() 方法在部分 Android 版本或窗口实现中存在限制,或未被正确实现,导致其修改无法被系统正确处理
Window.setType() 方法的设计局限
Window 类是一个抽象类,其具体实现(如系统中的 PhoneWindow)可能并未完整实现 setType() 方法的逻辑。
部分 Android 版本中,setType() 可能仅在窗口初始化时(未显示前)有效,一旦窗口已显示,调用 setType() 可能被系统忽略(因为窗口类型在显示后不允许动态修改,或修改需要特殊逻辑)。
在某些实现中,setType() 可能只是简单地修改了内部变量,却没有触发系统窗口管理器(WindowManager)的更新,导致类型变更未被系统感知
WindowManager.LayoutParams 是系统认可的配置载体
窗口的所有属性(包括类型 type)最终都由 WindowManager.LayoutParams 对象承载,系统通过该对象的参数来管理窗口的显示、层级、交互等行为。
当你直接修改 LayoutParams.type 后,调用 window.setAttributes(params) 时,系统会触发 WindowManager 的更新流程(通过 WindowManager.updateViewLayout()),重新验证并应用窗口参数,包括类型的变更。
结论
Window.setType() 方法可能因实现差异或系统限制,无法可靠地修改窗口类型;而通过 WindowManager.LayoutParams 修改 type 后调用 setAttributes(),是遵循系统规范的更新路径,能确保参数被正确传递给 WindowManager 并生效。因此,修改窗口类型时,推荐使用 LayoutParams + setAttributes() 的方式,这是更稳定、兼容更广的做法。
