android:state_window_focused仅在非全屏且窗口获焦点时生效,如dialog、popupwindow或分屏模式下的子窗口;全屏activity中恒为false,需配合其他状态使用且不适用于主题。

android:state_window_focused 在什么场景下才生效
它只在 Activity 处于「非全屏、且窗口有焦点」时起作用,比如弹出 Dialog、PopupWindow、或者多窗口模式(Split Screen / Freeform)下的子窗口。普通 Activity 全屏运行时,android:state_window_focused 永远为 false,样式不会应用。
常见错误现象:写了 android:state_window_focused="true" 却没效果,大概率是因为你正在调试的 Activity 是标准全屏模式,系统根本不会给它分配 window focus(只有顶层可见窗口才可能获得)。
- 仅适用于
selector的<item></item>中,不能用在View属性或主题里 - 必须配合
android:state_focused="false"或其他状态组合使用,单独用意义有限 - Android 7.0+ 在分屏模式下行为更稳定;Android 5.0–6.0 对该状态支持较弱,部分设备会忽略
和 android:state_focused 的关键区别
android:state_focused 看的是 View 是否获得输入焦点(比如 EditText 被点击后),而 android:state_window_focused 看的是整个窗口是否处于前台可交互状态。两者常被混淆,但触发条件完全不同。
典型使用场景:你想让一个按钮在「当前窗口是活跃弹窗」时显示高亮边框,但用户切到其他 App 或主 Activity 后自动恢复常态——这时靠 android:state_focused 做不到,必须用 android:state_window_focused。
-
android:state_focused受键盘/方向键导航影响,android:state_window_focused不依赖输入方式 - 当 Dialog 弹出时,宿主 Activity 的 window 失去焦点,其 selector 里的
android:state_window_focused="true"条件不满足 - 同一个 View 可能同时满足
state_focused="true"和state_window_focused="false"(例如:Dialog 内的 EditText 获得焦点,但 Dialog 所在窗口未获系统焦点)
selector 中正确写法与常见坑
必须把 android:state_window_focused="true" 放在更具体的 item 条件里,否则容易被默认项覆盖。顺序很重要:更严格的条件要写在前面。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="true" android:state_pressed="true">
<color android:color="@color/pressed_window_focused" />
</item>
<item android:state_window_focused="true">
<color android:color="@color/window_focused" />
</item>
<item>
<color android:color="@color/default_bg" />
</item>
</selector>
- 别漏掉 fallback 项(无任何 state 的
<item></item>),否则没匹配时可能渲染异常或透明 - 不要在同一个
<item></item>里混用互斥状态,例如android:state_window_focused="true"和android:state_window_focused="false" - 在 Android Studio Layout Editor 里预览时,
android:state_window_focused不会响应模拟操作,必须真机/模拟器运行并触发多窗口才能验证
替代方案:什么时候不该用它
如果你只是想区分「当前页面是否在前台」,android:state_window_focused 不可靠——Activity 切到后台时,它的 window 未必立刻失去焦点(尤其有 Dialog 或 Service UI 存在时)。这时候应该用生命周期回调或 onWindowFocusChanged() 主动控制状态。
- 需要精确感知页面可见性?优先监听
Activity.onWindowFocusChanged(boolean) - 要做主题级切换(如状态栏颜色)?改用
Window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)配合逻辑判断 - 目标是兼容旧设备?
android:state_window_focused在 Android 4.4 及以下基本无效,建议降级为android:state_focused+ 标志位变量
真正依赖这个状态的 UI 场景其实很少,多数时候开发者是误以为它等价于“页面可见”,结果卡在测试阶段反复调样式却看不到变化。











