一、問題描述
由于我們的項(xiàng)目是手機(jī)桌面的負(fù)一屏,沒有Activity而是通過Window.addView實(shí)現(xiàn)的。
所以無法直接使用常規(guī)的設(shè)置狀態(tài)欄的方式修改顏色。
最后通過分析原理,給View設(shè)置標(biāo)志位,結(jié)果還有問題,就有了這一篇文章了。
二、排查流程
一圖勝千言

狀態(tài)欄顏色修改不生效問題流程排查.png
- 場(chǎng)景
沉浸式,一個(gè)動(dòng)畫滾動(dòng)的場(chǎng)景下需要吸頂,然后對(duì)應(yīng)的狀態(tài)欄文字需要跟著變換顏色。 - 情況特殊
由于沒有Activity的存在,無法直接調(diào)用Activity的方法實(shí)現(xiàn)修改狀態(tài)欄 - 分析狀態(tài)欄修改原理 參考
其實(shí)就是給view設(shè)置標(biāo)志位,與Activity并沒有關(guān)系 - 分析誰調(diào)用了這個(gè)標(biāo)識(shí) Appearance_Light_Status_Bars
找到了是DisplayPolicy - 通過dump逐一排查當(dāng)前狀態(tài)
5.1. 肯定是appWindow,因?yàn)橛玫木褪荳indowManager.LayoutParams.TYPE_APPLICATION
5.2. attached應(yīng)該為null,因?yàn)椴皇莝ubWindow
5.3. 發(fā)現(xiàn)少了FullScreen標(biāo)識(shí),一般正常的Activity都有這個(gè)標(biāo)識(shí)。但我們是負(fù)一屏,沒有Activity,是通過window添加的,那么這個(gè)添加的參數(shù)是否有問題。 - 查詢isFullScreen方法的判斷標(biāo)準(zhǔn)
果然問題就在這里,我們?cè)仍O(shè)置的寬高直接讀取了屏幕高寬,并非設(shè)置的MatchParent
三、相應(yīng)的源碼
DisplayPolicy
/**
* Called following layout of all window to apply policy to each window.
*
* @param win The window being positioned.
* @param attrs The LayoutParams of the window.
* @param attached For sub-windows, the window it is attached to. Otherwise null.
*/
public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
WindowState attached, WindowState imeTarget) {
//省略若干...
boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type < FIRST_SYSTEM_WINDOW;
//省略若干...
// Check the windows that overlap with system bars to determine system bars' appearance.
if ((appWindow && attached == null && attrs.isFullscreen())
|| attrs.type == TYPE_VOICE_INTERACTION) {
//省略若干...
// Cache app windows that is overlapping with the status bar to determine appearance
// of status bar.
if (mStatusBar != null
&& sTmpRect.setIntersect(win.getFrame(), mStatusBar.getFrame())
&& !mStatusBarBackgroundCheckedBounds.contains(sTmpRect)) {
mStatusBarBackgroundWindows.add(win);
mStatusBarBackgroundCheckedBounds.union(sTmpRect);
if (!mStatusBarColorCheckedBounds.contains(sTmpRect)) {
mStatusBarAppearanceRegionList.add(new AppearanceRegion(
win.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS,
new Rect(win.getFrame())));
mStatusBarColorCheckedBounds.union(sTmpRect);
}
}
}
//省略若干...
}
WindowManager.LayoutParams
/**
* @hide
* @return True if the layout parameters will cause the window to cover the full screen;
* false otherwise.
*/
public boolean isFullscreen() {
return x == 0 && y == 0
&& width == WindowManager.LayoutParams.MATCH_PARENT
&& height == WindowManager.LayoutParams.MATCH_PARENT;
}