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.

enter image description here


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);
}