Created
January 28, 2015 12:29
-
-
Save shivam340/51b7be8a6f8de70ff030 to your computer and use it in GitHub Desktop.
to change color of status Bar in kitkat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.healthkart.pillreminder.utils; | |
import android.annotation.SuppressLint; | |
import android.annotation.TargetApi; | |
import android.app.Activity; | |
import android.content.Context; | |
import android.content.res.Configuration; | |
import android.content.res.Resources; | |
import android.content.res.TypedArray; | |
import android.os.Build; | |
import android.util.DisplayMetrics; | |
import android.view.Gravity; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.Window; | |
import android.view.WindowManager; | |
import android.widget.FrameLayout.LayoutParams; | |
import java.lang.reflect.Method; | |
/** | |
* Class to manage status bar tint effects when using KitKat | |
* translucent system UI modes. | |
*/ | |
public class StatusBarColor { | |
static { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
try { | |
Class c = Class.forName("android.os.SystemProperties"); | |
Method m = c.getDeclaredMethod("get", String.class); | |
m.setAccessible(true); | |
sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys"); | |
} catch (Throwable e) { | |
sNavBarOverride = null; | |
} | |
} | |
} | |
/** | |
* The default system bar tint color value. | |
*/ | |
public static final int DEFAULT_TINT_COLOR = 0x99000000; | |
private static String sNavBarOverride; | |
private final SystemBarConfig mConfig; | |
private boolean mStatusBarAvailable; | |
private boolean mNavBarAvailable; | |
private boolean mStatusBarTintEnabled; | |
private View mStatusBarTintView; | |
private View mNavBarTintView; | |
/** | |
* Constructor. Call this in the host activity onCreate method after its | |
* content view has been set. You should always create new instances when | |
* the host activity is recreated. | |
* | |
* @param activity The host activity. | |
*/ | |
@TargetApi(19) | |
public StatusBarColor(Activity activity) { | |
Window win = activity.getWindow(); | |
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView(); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
// check theme attrs | |
int[] attrs = {android.R.attr.windowTranslucentStatus, | |
android.R.attr.windowTranslucentNavigation}; | |
TypedArray a = activity.obtainStyledAttributes(attrs); | |
try { | |
mStatusBarAvailable = a.getBoolean(0, false); | |
mNavBarAvailable = a.getBoolean(1, false); | |
} finally { | |
a.recycle(); | |
} | |
// check window flags | |
WindowManager.LayoutParams winParams = win.getAttributes(); | |
int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; | |
if ((winParams.flags & bits) != 0) { | |
mStatusBarAvailable = true; | |
} | |
bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; | |
if ((winParams.flags & bits) != 0) { | |
mNavBarAvailable = true; | |
} | |
} | |
mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable); | |
// device might not have virtual navigation keys | |
if (!mConfig.hasNavigtionBar()) { | |
mNavBarAvailable = false; | |
} | |
if (mStatusBarAvailable) { | |
setupStatusBarView(activity, decorViewGroup); | |
} | |
if (mNavBarAvailable) { | |
setupNavBarView(activity, decorViewGroup); | |
} | |
} | |
/** | |
* Enable tinting of the system status bar. | |
* <p/> | |
* If the platform is running Jelly Bean or earlier, or translucent system | |
* UI modes have not been enabled in either the theme or via window flags, | |
* then this method does nothing. | |
* | |
* @param enabled True to enable tinting, false to disable it (default). | |
*/ | |
public void setStatusBarTintEnabled(boolean enabled) { | |
mStatusBarTintEnabled = enabled; | |
if (mStatusBarAvailable) { | |
mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE); | |
} | |
} | |
/** | |
* Apply the specified color tint to the system status bar. | |
* | |
* @param color The color of the background tint. | |
*/ | |
public void setStatusBarTintColor(int color) { | |
if (mStatusBarAvailable) { | |
mStatusBarTintView.setBackgroundColor(color); | |
} | |
} | |
/** | |
* Apply the specified drawable or color resource to the system status bar. | |
* | |
* @param res The identifier of the resource. | |
*/ | |
public void setStatusBarTintResource(int res) { | |
if (mStatusBarAvailable) { | |
mStatusBarTintView.setBackgroundResource(res); | |
} | |
} | |
private void setupStatusBarView(Context context, ViewGroup decorViewGroup) { | |
mStatusBarTintView = new View(context); | |
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight()); | |
params.gravity = Gravity.TOP; | |
if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) { | |
params.rightMargin = mConfig.getNavigationBarWidth(); | |
} | |
mStatusBarTintView.setLayoutParams(params); | |
mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR); | |
mStatusBarTintView.setVisibility(View.GONE); | |
decorViewGroup.addView(mStatusBarTintView); | |
} | |
private void setupNavBarView(Context context, ViewGroup decorViewGroup) { | |
mNavBarTintView = new View(context); | |
LayoutParams params; | |
if (mConfig.isNavigationAtBottom()) { | |
params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight()); | |
params.gravity = Gravity.BOTTOM; | |
} else { | |
params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT); | |
params.gravity = Gravity.RIGHT; | |
} | |
mNavBarTintView.setLayoutParams(params); | |
mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR); | |
mNavBarTintView.setVisibility(View.GONE); | |
decorViewGroup.addView(mNavBarTintView); | |
} | |
/** | |
* Class which describes system bar sizing and other characteristics for the current | |
* device configuration. | |
*/ | |
public static class SystemBarConfig { | |
private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height"; | |
private final int mStatusBarHeight; | |
private final boolean mHasNavigationBar; | |
private final int mNavigationBarHeight; | |
private final int mNavigationBarWidth; | |
private final boolean mInPortrait; | |
private final float mSmallestWidthDp; | |
private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) { | |
Resources res = activity.getResources(); | |
mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT); | |
mSmallestWidthDp = getSmallestWidthDp(activity); | |
mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME); | |
mNavigationBarHeight = 0; | |
mNavigationBarWidth = 0; | |
mHasNavigationBar = false; | |
} | |
private int getInternalDimensionSize(Resources res, String key) { | |
int result = 0; | |
int resourceId = res.getIdentifier(key, "dimen", "android"); | |
if (resourceId > 0) { | |
result = res.getDimensionPixelSize(resourceId); | |
} | |
return result; | |
} | |
@SuppressLint("NewApi") | |
private float getSmallestWidthDp(Activity activity) { | |
DisplayMetrics metrics = new DisplayMetrics(); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | |
activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics); | |
} else { | |
// TODO this is not correct, but we don't really care pre-kitkat | |
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); | |
} | |
float widthDp = metrics.widthPixels / metrics.density; | |
float heightDp = metrics.heightPixels / metrics.density; | |
return Math.min(widthDp, heightDp); | |
} | |
/** | |
* Should a navigation bar appear at the bottom of the screen in the current | |
* device configuration? A navigation bar may appear on the right side of | |
* the screen in certain configurations. | |
* | |
* @return True if navigation should appear at the bottom of the screen, False otherwise. | |
*/ | |
public boolean isNavigationAtBottom() { | |
return (mSmallestWidthDp >= 600 || mInPortrait); | |
} | |
/** | |
* Get the height of the system status bar. | |
* | |
* @return The height of the status bar (in pixels). | |
*/ | |
public int getStatusBarHeight() { | |
return mStatusBarHeight; | |
} | |
/** | |
* Does this device have a system navigation bar? | |
* | |
* @return True if this device uses soft key navigation, False otherwise. | |
*/ | |
public boolean hasNavigtionBar() { | |
return mHasNavigationBar; | |
} | |
/** | |
* Get the height of the system navigation bar. | |
* | |
* @return The height of the navigation bar (in pixels). If the device does not have | |
* soft navigation keys, this will always return 0. | |
*/ | |
public int getNavigationBarHeight() { | |
return mNavigationBarHeight; | |
} | |
/** | |
* Get the width of the system navigation bar when it is placed vertically on the screen. | |
* | |
* @return The width of the navigation bar (in pixels). If the device does not have | |
* soft navigation keys, this will always return 0. | |
*/ | |
public int getNavigationBarWidth() { | |
return mNavigationBarWidth; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment