10

I would like to make something like this Gradient status bar

for Android 5.0 and above?

How can I implement this? I can not found any solution on StackOverFlow or on android developer site.

I suggested that I can make status bar transparent and draw gradient drawable under status bar. But there are few problems.

First problem is that usual gradient from shape drawable doesn't support Material Design spec http://www.google.com/design/spec/style/imagery.html Material Design gradient

Second problem is that I can not fit map fragment to windows via android:fitsSystemWindows="true".

Sergei Vasilenko
  • 2,313
  • 2
  • 27
  • 38

1 Answers1

0

Formula that gives approximately same plot as shown on the site of Material Design is:

y = 3/(4*(x+0.5)) - 0.5

I've tried several ways to draw hyperboloid gradient via Canvas and found the fastest solution.

public class HyperbolaGradientDrawable extends Drawable {

private static final int ALPHA_DEFAULT = (int) (0.6f * 255);

private int mAlpha = ALPHA_DEFAULT;
private int mColor;
private Rect  mBmpRect = new Rect();
private int[] mColors  = new int[0];
private Bitmap mBmp;

@Override
public void draw(Canvas canvas) {
    Rect bounds = getBounds();
    if (mColors.length != bounds.height()) {
        int alpha;
        float y, alphaRelative;
        mColors = new int[bounds.height()];
        for (int i = 0; i < bounds.height(); i++) {
            y = ((float) i) / bounds.height();
            // this function gives approximately 0.5 of the bearing alpha at 3/10ths closed to the darker end
            alphaRelative = 3 / (4 * (y + 0.5f)) - 0.5f;
            alpha = (int) (alphaRelative * mAlpha);
            mColors[i] = alpha << 24 | mColor;
        }
        mBmp = Bitmap.createBitmap(mColors, 1, bounds.height(), Bitmap.Config.ARGB_8888);
        mBmpRect.set(0, 0, 1, bounds.height());
    }
    canvas.drawBitmap(mBmp, mBmpRect, bounds, null);
}

public void setColor(int color) {
    // remove alpha chanel
    mColor = color & 0x00FFFFFF;
}

@Override
public void setAlpha(int alpha) {
    mAlpha = alpha;
}

@Override
public void setColorFilter(ColorFilter colorFilter) {

}

@Override
public int getOpacity() {
    return PixelFormat.TRANSLUCENT;
}
}

I know that Google recommend to do not create new objects in draw method, but it works faster than drawing line by line through Canvas.

You can look at comparison of several ways in demo project

Sergei Vasilenko
  • 2,313
  • 2
  • 27
  • 38