Set status bar color from DialogFragment
Asked Answered
S

4

18

I'm creating an app which changes status bar color dynamically.

My method in main Activity class works fine when called from any fragment. Fragments are placed in Activity pager:

public void setStatusBarColorIfPossible(int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        getWindow().setStatusBarColor(color);
    }
}

However, in DialogFragment which is created in any fragment and made fullscreen, calling my method has no effect. Status bar is instantly black (as set in styles.xml) and I can't change it.

public class AddOrEditWeekPlanDialog extends DialogFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, R.style.MyDialog);
    }

    @Override
    public void onStart() {
        super.onStart();
        Dialog d = getDialog();
        if (d!=null){
            int width = ViewGroup.LayoutParams.MATCH_PARENT;
            int height = ViewGroup.LayoutParams.MATCH_PARENT;
            d.getWindow().setLayout(width, height);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_dialog, container, false);
        Button button = (Button)root.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((ThermostatActivity) getActivity()).setStatusBarColorIfPossible(0xFF0D47A1);
            }
        });

        return root;
    }

    @Override
    public void onResume() {
        super.onResume();

    }
}

styles.xml:

// Set in manifest for main activity
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
</style>

// Set in dialog class
<style name="MyDialog" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsFloating">false</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
</style>

resources.xml:

<resources>
    <color name="colorPrimary">#FFB72020</color>
    <color name="colorPrimaryDark">#000</color>
    <color name="textColor">#fff</color>
    <color name="tabsScrollColor">#fff</color>
</resources>

Anyone can explain me why?

Santanasantayana answered 29/7, 2015 at 12:39 Comment(0)
S
17

In order to setStatusBarColor you need to set the flag: FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS

"Flag indicating that this Window is responsible for drawing the background for the system bars." (Google API level 21)

Try this code:

public void setStatusBarColorIfPossible(int color) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
       getWindow().setStatusBarColor(color);
    }
}
Shulem answered 7/1, 2016 at 14:43 Comment(3)
This causes the dialog to draw contents under the nav bar as well. For those using a BottomSheetDialog, this is especially problematic because it places the nav bar buttons over your dialog.Prelusive
Do you find a solution? Thank you @PrelusiveMistress
after adding flag FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS dialog stoped to resizing on Keyboard open, have any idea about issue ?Sanctus
C
5

This works for me.

 @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Objects.requireNonNull(Objects.requireNonNull(getDialog()).getWindow()).addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        Objects.requireNonNull(Objects.requireNonNull(getDialog()).getWindow()).setStatusBarColor(getResources().getColor(R.color.light_green_400));
    }

}
Consecrate answered 16/7, 2019 at 15:31 Comment(0)
C
0

use FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS and change hight child in index 0 in getDecorView.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       if (getDialog().getWindow() != null) {

              // Flag
              getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 

              // DeviceScreenHeight
              WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
              DisplayMetrics displayMetrics = new DisplayMetrics();
              windowManager.getDefaultDisplay().getMetrics(displayMetrics);
              int deviceScreenHeight = displayMetrics.heightPixels;

              // Change height child At index zero 
              ((ViewGroup) getDialog().getWindow().getDecorView().getRootView()).getChildAt(0).getLayoutParams().height = deviceScreenHeight;

        }
}
Cupping answered 20/12, 2017 at 7:14 Comment(0)
T
0
<style name="MyDialogStyle" parent="Theme.AppCompat.Dialog">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowFullscreen">false</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:statusBarColor" tools:targetApi="l">@color/white</item>

</style>

you can change color by adding status bar color from style like this.

Thorrlow answered 28/9, 2021 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.