通俗易懂的讲解:Android窗口属性全解析

将用"窗口管理局"的比喻,结合源码解析这篇文章的核心内容。窗口属性就像店铺的经营许可证,决定了窗口如何显示、如何交互以及如何与其他窗口共存。


🏢 第一章:窗口属性登记表(LayoutParams)

在Android系统中,每个窗口在创建时都需要填写一份"属性登记表",这就是WindowManager.LayoutParams类。它包含三大核心属性:

scala 复制代码
java
Copy
public static class LayoutParams extends ViewGroup.LayoutParams {
    public int type;          // 窗口类型(决定层级)
    public int flags;         // 窗口标志(行为控制)
    public int softInputMode; // 软键盘交互模式
}

📋 第二章:窗口类型(Type)------ 决定店铺等级

窗口类型决定了窗口的​​层级关系​​(Z-Order),就像商业街的店铺位置:高档商铺在显眼位置,小摊位在角落。类型分为三大类:

1. ​​应用程序窗口(1~99)​

arduino 复制代码
java
Copy
public static final int TYPE_APPLICATION = 2;        // 普通App窗口
public static final int TYPE_APPLICATION_STARTING = 3; // App启动时的临时窗口
  • ​比喻​:正规商铺(如Activity)
  • ​特点​:需要用户交互,位于中间层级

2. ​​子窗口(1000~1999)​

arduino 复制代码
java
Copy
public static final int TYPE_APPLICATION_PANEL = 1000; // 面板型子窗口
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 对话框
  • ​比喻​:商铺内的展示柜(必须依附于主店铺)
  • ​关键特性​ :必须指定父窗口(token属性)
  • ​典型代表​:Dialog

3. ​​系统窗口(2000~2999)​

arduino 复制代码
java
Copy
public static final int TYPE_STATUS_BAR = 2000;     // 状态栏
public static final int TYPE_TOAST = 2005;          // Toast
public static final int TYPE_PHONE = 2002;          // 电话窗口(来电显示)
  • ​比喻​:公共设施(如路灯、公交站)
  • ​权限要求​ :需要声明SYSTEM_ALERT_WINDOW权限
  • ​特殊规则​:Toast(TYPE_TOAST)在Android 7.1后无需权限

🎚️ 层级规则(Z-Order)

  • ​基本规则​​:Type值越大,窗口层级越高(越靠近用户)

  • ​示例​​:

    css 复制代码
    A[Activity<br>TYPE=2] --> B[Dialog<br>TYPE=1003]
    B --> C[Toast<br>TYPE=2005]

    实际显示顺序:Toast > Dialog > Activity


🚩 第三章:窗口标志(Flags)------ 经营行为规范

Flags控制窗口的​​交互行为​​,就像商铺的经营规则(是否允许夜间营业、是否接受刷卡等)。常用Flags如下:

Flag值 作用描述
FLAG_NOT_FOCUSABLE 窗口不获取焦点(无法接收输入事件)
FLAG_NOT_TOUCHABLE 窗口不响应触摸事件(事件会穿透)
FLAG_KEEP_SCREEN_ON 窗口可见时保持屏幕常亮
FLAG_FULLSCREEN 全屏显示(隐藏状态栏)
FLAG_SHOW_WHEN_LOCKED 在锁屏界面之上显示(用于闹钟提醒)
FLAG_LAYOUT_NO_LIMITS 允许窗口超出屏幕边界

⚙️ 设置Flags的三种方式

  1. ​动态添加​​(推荐):

    scss 复制代码
    java
    Copy
    // 示例:设置全屏
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
  2. ​覆盖设置​​:

    scss 复制代码
    java
    Copy
    // 清空旧Flags并设置新值
    getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
  3. ​通过LayoutParams设置​​(适用于系统窗口):

    ini 复制代码
    java
    Copy
    LayoutParams params = new LayoutParams();
    params.flags = FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE;
    windowManager.addView(view, params);

⌨️ 第四章:软键盘模式(SoftInputMode)------ 避免键盘遮挡

控制软键盘弹出时​​窗口的调整行为​​,就像商铺如何应对临时检查(是调整货架还是原地等待)。

常用模式:

模式值 行为描述
SOFT_INPUT_ADJUST_RESIZE 窗口调整大小(内容自动上移)
SOFT_INPUT_ADJUST_PAN 窗口平移(保持输入框可见)
SOFT_INPUT_STATE_HIDDEN 进入窗口时默认隐藏键盘
SOFT_INPUT_STATE_ALWAYS_VISIBLE 进入窗口时总是显示键盘

⚙️ 设置方式:

  1. ​在AndroidManifest中声明​​:

    ini 复制代码
    xml
    Copy
    <activity android:windowSoftInputMode="adjustResize|stateHidden" />
  2. ​代码动态设置​​:

    scss 复制代码
    java
    Copy
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

💡 第五章:实战示例解析

案例1:全屏游戏窗口

scss 复制代码
java
Copy
// 设置全屏 + 保持常亮 + 隐藏导航栏
getWindow().addFlags(
    FLAG_FULLSCREEN |
    FLAG_KEEP_SCREEN_ON |
    FLAG_LAYOUT_NO_LIMITS
);

案例2:锁屏显示闹钟

scss 复制代码
java
Copy
// 锁屏显示 + 触摸穿透 + 点亮屏幕
getWindow().addFlags(
    FLAG_SHOW_WHEN_LOCKED |
    FLAG_NOT_TOUCHABLE |
    FLAG_TURN_SCREEN_ON
);

案例3:聊天界面避免键盘遮挡

scss 复制代码
java
Copy
// 键盘弹出时调整布局 + 默认隐藏键盘
getWindow().setSoftInputMode(
    SOFT_INPUT_ADJUST_RESIZE | 
    SOFT_INPUT_STATE_HIDDEN
);

📊 属性优先级与冲突处理

当多个属性冲突时,WMS按以下优先级处理:

  1. ​Type值​:决定基础层级(系统窗口 > 子窗口 > 应用窗口)
  2. ​Flags​ :修改交互行为(如FLAG_NOT_FOCUSABLE会覆盖默认焦点行为)
  3. ​软键盘模式​:仅当键盘弹出时生效

⚠️ 注意:系统窗口需要权限!

Android 6.0+ 使用TYPE_TOAST无需权限,其他系统窗口需:

ini 复制代码
xml
Copy
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

总结:窗口属性三大件

  1. ​Type​:决定窗口层级(你是谁?)
  2. ​Flags​:控制交互行为(你能做什么?)
  3. ​SoftInputMode​:键盘交互策略(如何应对输入?)

理解这些属性,就能精准控制窗口的显示逻辑,避免"键盘遮挡输入框"、"全屏时状态栏残留"等常见问题。下一讲我们将深入Window的添加过程!

相关推荐
一只柠檬新5 小时前
Web和Android的渐变角度区别
android
志旭5 小时前
从0到 1实现BufferQueue GraphicBuffer fence HWC surfaceflinger
android
_一条咸鱼_5 小时前
Android Runtime堆内存架构设计(47)
android·面试·android jetpack
用户2018792831676 小时前
WMS(WindowManagerService的诞生
android
openinstall6 小时前
A/B测试如何借力openinstall实现用户价值深挖?
android·ios·html
二流小码农6 小时前
鸿蒙开发:资讯项目实战之项目初始化搭建
android·ios·harmonyos
志旭7 小时前
android15 vsync源码分析
android
志旭7 小时前
Android 14 HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia
android
whysqwhw7 小时前
Egloo 高级用法
android