通俗易懂的讲解: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的添加过程!

相关推荐
雨白10 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk10 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING11 小时前
RN容器启动优化实践
android·react native
恋猫de小郭14 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker19 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴19 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab1 天前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农2 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos