fitSystemWindow的作用
在指定的view上添加padding慷嗜,來空出系統(tǒng)的狀態(tài)欄和導(dǎo)航欄的空間淀弹。通常配合透明狀態(tài)欄使用。
失效的原因
在一個(gè)Activity的View樹中庆械,fitSystemWindow的傳遞會(huì)被上層攔截薇溃。
WindowInsets
windowInsets保存了窗口信息。包括系統(tǒng)控件占用的窗口空間等缭乘。狀態(tài)欄的高度就是通過這個(gè)對(duì)象傳遞的沐序。
自下而上傳遞WindowInsets
在ViewGroup中傳遞WindowInsets的方法
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
insets = super.dispatchApplyWindowInsets(insets);
if (!insets.isConsumed()) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
insets = getChildAt(i).dispatchApplyWindowInsets(insets);
if (insets.isConsumed()) {
break;
}
}
}
return insets;
}
當(dāng)有一個(gè)chid消費(fèi)了windowInsets,那就停止傳遞。
失效問題
從上面一節(jié)可以看出策幼,失效的真正原因是WindowInsets被上層view消費(fèi)了邑时。所以沒有傳遞下來。
解決方法 api>=20
自定義上層ViewGroup特姐。以FrameLayout為例
public class WindowInsertFrameLayout extends FrameLayout {
public WindowInsertFrameLayout(Context context) {
this(context,null);
}
public WindowInsertFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
//當(dāng)有child添加時(shí)晶丘,請(qǐng)求再次分發(fā)一次WindowInsets
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
requestApplyInsets();
}
}
@Override
public void onChildViewRemoved(View parent, View child) {
}
});
}
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
//重寫分發(fā)方法,不判斷是否消費(fèi)
for (int index = 0; index < getChildCount(); index++) {
getChildAt(index).dispatchApplyWindowInsets(insets);
}
}
return insets;
}
}
解決方法api<=20
fitSystemWindow
從19開始支持唐含,
由于dispatchApplyWindowInsets
方法只對(duì)20及20以上api生效浅浮,而19-20之間處理分發(fā)的fitSystemWindows
方法是protected方法〗菘荩考慮到20以下的設(shè)備已經(jīng)比較少了滚秩,因此可以在20以下的設(shè)備上不使用透明狀態(tài)欄。這樣就解決了fitSystemWindow再20以下設(shè)備上可能失效的問題淮捆。
如果幫助到您的話郁油,可以點(diǎn)一下喜歡。