0

I'm trying to make my status bar show a gradient exactly like the background below it, much like in this question: How to apply gradient to status bar in android?

However the answer to that question causes the entire layout to extend into the navigation bar, something which I want to avoid.

I can't find a way that doesn't use WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS and have the status bar either be completely transparent or have it show a gradient (the same one as the one below it.

Is there a way I can have the status bar show a gradient, and not affect the navigation bar? Ideally what is seen is the status bar is "invisible", where the power/wifi/etc icons are still visible but the colors seen are the gradient of the layout that is currently active.

Quorrin
  • 99
  • 1
  • 3
  • 10

3 Answers3

4

One way to achieve your goal.

Set window background as gradient and status bar color is transparent.

Here is sample code.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
     Window window = getWindow();
     Drawable background = getResources().getDrawable(R.drawable.bg_gradient); //bg_gradient is your gradient.
     window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
     window.setStatusBarColor(getResources().getColor(android.R.color.transparent));
     window.setBackgroundDrawable(background);
}
Niranj Patel
  • 32,980
  • 10
  • 97
  • 133
2

For this type of task. You have to set first FLAG_LAYOUT_NO_LIMITS flag in your activity or fragment as,

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cart);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    }

Now, in your XML just set a view at top of layout like,

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <View
        android:id="@+id/status_bar_view"
        android:background="#000"       
        android:layout_width="match_parent"
        android:layout_height="24dp"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="22dp">
                 //main layout here.
    </RelativeLayout>        
</LinearLayout>

So, the top view takes the place of statusbar in layout and you can set background of view as you want. In above view, I just used black color you can also set a gradient as a background.

EDIT

But also we have to set view dynamically because height of statusbar is different on each device according to screen size. So, statusbar height you calculate as,

public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    } 

Above method returns the statusbar height for each device. You can set this as a height for view. So your view, looks exactly like statusbar in size.

Aditya
  • 3,525
  • 1
  • 31
  • 38
  • it works but what if I don't remove the navigationbar ? because with this code , the activity content goes below the navigation bar – Navid Abutorab Dec 19 '19 at 06:05
0

func setGradientStatusBar() {

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = CGRect(x:0, y:-20, width:375, height:64)
    let colorTop = UIColor(red: 85/255, green: 66/255, blue: 35/255, alpha: 1.0).cgColor
    let colorBottom = UIColor(red: 169/255, green: 132/255, blue: 69/255, alpha: 1.0).cgColor
    gradientLayer.colors = [ colorTop, colorBottom]
    gradientLayer.locations = [ 0.0, 1.0]
    gradientLayer.frame = CGRect(x:0, y:0, width:UIScreen.main.bounds.width, height:UIApplication.shared.statusBarFrame.height)
    let window: UIWindow? = UIApplication.shared.keyWindow
    let view = UIView()
    view.backgroundColor = UIColor.clear
    view.translatesAutoresizingMaskIntoConstraints = false
    view.frame = CGRect(x: 0, y: 0, width: (window?.frame.width)!, height: self.view.frame.height * 0.07)
    view.layer.addSublayer(gradientLayer)
    window?.addSubview(view)
}