fitSystemWindows programmatically for status bar transparency
Well, you are in dilemma situation there, because from one hand you need to apply insets (because Toolbar
should be correctly padded), and on the other hand you should not apply insets (because you want ImageView
to be drawn under status bar).
Turns out there's a nice API provided by the framework for that case:
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin =
insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
Assuming your root layout has android:fitsSystemWindows="true"
, now appropriate insets would be applied to your Toolbar
only, and not the ImageView
.
But, there's a problem.
The problem is that your root layout is RelativeLayout
, which doesn't dispatch its children any information about insets. Neither do its sibling layouts (LinearLayout
, FrameLayout
).
If you had as a root layout one of "materialish" layouts (CoordinatorLayout
, DrawerLayout
), then children would be dispatched those window insets.
The other option is to subclass RelativeLayout
and dispatch WindowInsets
to
children manually.
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++)
getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets
return insets;
}
You can see this answer for a detailed explanation with precisely same requirement you have.
I have resolve this question in 4.4
if(test){
Log.d(TAG, "fit true ");
relativeLayout.setFitsSystemWindows(true);
relativeLayout.requestFitSystemWindows();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}else {
Log.d(TAG, "fit false");
relativeLayout.setFitsSystemWindows(false);
relativeLayout.requestFitSystemWindows();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}