1 sdk>19
2 思路,window的设置透明的,然后在decorView加上一个和状态栏的一样的高的view就可以了,颜色,设置颜色。
3 解决了 从全屏幕到不是全屏幕的会反生页面会卡一下的效果,思路:在给contentview默认加一个padding的值大小等于状态栏的高度
4 后来遇到了将一张图片设为状态栏背景色
本地图片:借用
publicclassSystemBarTintManager {
static{
// Android allows a system property to override the presence of the navigation bar.
// Used by the emulator.
// See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
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.
*/
publicstaticfinalintDEFAULT_TINT_COLOR =0x99000000;
privatestaticString sNavBarOverride;
privatefinalSystemBarConfig mConfig;
privatebooleanmStatusBarAvailable;
privatebooleanmNavBarAvailable;
privatebooleanmStatusBarTintEnabled;
privatebooleanmNavBarTintEnabled;
privateView mStatusBarTintView;
privateView 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)
publicSystemBarTintManager(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();
intbits = 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 =newSystemBarConfig(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.
*
* 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).
*/
publicvoidsetStatusBarTintEnabled(booleanenabled) {
mStatusBarTintEnabled = enabled;
if(mStatusBarAvailable) {
mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
}
}
/**
* Enable tinting of the system navigation bar.
*
* If the platform does not have soft navigation keys, 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).
*/
publicvoidsetNavigationBarTintEnabled(booleanenabled) {
mNavBarTintEnabled = enabled;
if(mNavBarAvailable) {
mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
}
}
/**
* Apply the specified color tint to all system UI bars.
*
* @param color The color of the background tint.
*/
publicvoidsetTintColor(intcolor) {
setStatusBarTintColor(color);
setNavigationBarTintColor(color);
}
/**
* Apply the specified drawable or color resource to all system UI bars.
*
* @param res The identifier of the resource.
*/
publicvoidsetTintResource(intres) {
setStatusBarTintResource(res);
setNavigationBarTintResource(res);
}
/**
* Apply the specified drawable to all system UI bars.
*
* @param drawable The drawable to use as the background, or null to remove it.
*/
publicvoidsetTintDrawable(Drawable drawable) {
setStatusBarTintDrawable(drawable);
setNavigationBarTintDrawable(drawable);
}
/**
* Apply the specified alpha to all system UI bars.
*
* @param alpha The alpha to use
*/
publicvoidsetTintAlpha(floatalpha) {
setStatusBarAlpha(alpha);
setNavigationBarAlpha(alpha);
}
/**
* Apply the specified color tint to the system status bar.
*
* @param color The color of the background tint.
*/
publicvoidsetStatusBarTintColor(intcolor) {
if(mStatusBarAvailable) {
mStatusBarTintView.setBackgroundColor(color);
}
}
/**
* Apply the specified drawable or color resource to the system status bar.
*
* @param res The identifier of the resource.
*/
publicvoidsetStatusBarTintResource(intres) {
if(mStatusBarAvailable) {
mStatusBarTintView.setBackgroundResource(res);
}
}
/**
* Apply the specified drawable to the system status bar.
*
* @param drawable The drawable to use as the background, or null to remove it.
*/
@SuppressWarnings("deprecation")
publicvoidsetStatusBarTintDrawable(Drawable drawable) {
if(mStatusBarAvailable) {
mStatusBarTintView.setBackgroundDrawable(drawable);
}
}
/**
* Apply the specified alpha to the system status bar.
*
* @param alpha The alpha to use
*/
@TargetApi(11)
publicvoidsetStatusBarAlpha(floatalpha) {
if(mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mStatusBarTintView.setAlpha(alpha);
}
}
/**
* Apply the specified color tint to the system navigation bar.
*
* @param color The color of the background tint.
*/
publicvoidsetNavigationBarTintColor(intcolor) {
if(mNavBarAvailable) {
mNavBarTintView.setBackgroundColor(color);
}
}
/**
* Apply the specified drawable or color resource to the system navigation bar.
*
* @param res The identifier of the resource.
*/
publicvoidsetNavigationBarTintResource(intres) {
if(mNavBarAvailable) {
mNavBarTintView.setBackgroundResource(res);
}
}
/**
* Apply the specified drawable to the system navigation bar.
*
* @param drawable The drawable to use as the background, or null to remove it.
*/
@SuppressWarnings("deprecation")
publicvoidsetNavigationBarTintDrawable(Drawable drawable) {
if(mNavBarAvailable) {
mNavBarTintView.setBackgroundDrawable(drawable);
}
}
/**
* Apply the specified alpha to the system navigation bar.
*
* @param alpha The alpha to use
*/
@TargetApi(11)
publicvoidsetNavigationBarAlpha(floatalpha) {
if(mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mNavBarTintView.setAlpha(alpha);
}
}
/**
* Get the system bar configuration.
*
* @return The system bar configuration for the current device configuration.
*/
publicSystemBarConfig getConfig() {
returnmConfig;
}
/**
* Is tinting enabled for the system status bar?
*
* @return True if enabled, False otherwise.
*/
publicbooleanisStatusBarTintEnabled() {
returnmStatusBarTintEnabled;
}
/**
* Is tinting enabled for the system navigation bar?
*
* @return True if enabled, False otherwise.
*/
publicbooleanisNavBarTintEnabled() {
returnmNavBarTintEnabled;
}
privatevoidsetupStatusBarView(Context context, ViewGroup decorViewGroup) {
mStatusBarTintView =newView(context);
LayoutParams params =newLayoutParams(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);
}
privatevoidsetupNavBarView(Context context, ViewGroup decorViewGroup) {
mNavBarTintView =newView(context);
LayoutParams params;
if(mConfig.isNavigationAtBottom()) {
params =newLayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
params.gravity = Gravity.BOTTOM;
}else{
params =newLayoutParams(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.
*
*/
publicstaticclassSystemBarConfig {
privatestaticfinalString STATUS_BAR_HEIGHT_RES_NAME ="status_bar_height";
privatestaticfinalString NAV_BAR_HEIGHT_RES_NAME ="navigation_bar_height";
privatestaticfinalString NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME ="navigation_bar_height_landscape";
privatestaticfinalString NAV_BAR_WIDTH_RES_NAME ="navigation_bar_width";
privatestaticfinalString SHOW_NAV_BAR_RES_NAME ="config_showNavigationBar";
privatefinalbooleanmTranslucentStatusBar;
privatefinalbooleanmTranslucentNavBar;
privatefinalintmStatusBarHeight;
privatefinalintmActionBarHeight;
privatefinalbooleanmHasNavigationBar;
privatefinalintmNavigationBarHeight;
privatefinalintmNavigationBarWidth;
privatefinalbooleanmInPortrait;
privatefinalfloatmSmallestWidthDp;
privateSystemBarConfig(Activity activity,booleantranslucentStatusBar,booleantraslucentNavBar) {
Resources res = activity.getResources();
mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
mSmallestWidthDp = getSmallestWidthDp(activity);
mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
mActionBarHeight = getActionBarHeight(activity);
mNavigationBarHeight = getNavigationBarHeight(activity);
mNavigationBarWidth = getNavigationBarWidth(activity);
mHasNavigationBar = (mNavigationBarHeight >0);
mTranslucentStatusBar = translucentStatusBar;
mTranslucentNavBar = traslucentNavBar;
}
@TargetApi(14)
privateintgetActionBarHeight(Context context) {
intresult =0;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TypedValue tv =newTypedValue();
context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv,true);
result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
returnresult;
}
@TargetApi(14)
privateintgetNavigationBarHeight(Context context) {
Resources res = context.getResources();
intresult =0;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if(hasNavBar(context)) {
String key;
if(mInPortrait) {
key = NAV_BAR_HEIGHT_RES_NAME;
}else{
key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
}
returngetInternalDimensionSize(res, key);
}
}
returnresult;
}
@TargetApi(14)
privateintgetNavigationBarWidth(Context context) {
Resources res = context.getResources();
intresult =0;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if(hasNavBar(context)) {
returngetInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
}
}
returnresult;
}
@TargetApi(14)
privatebooleanhasNavBar(Context context) {
Resources res = context.getResources();
intresourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME,"bool","android");
if(resourceId !=0) {
booleanhasNav = res.getBoolean(resourceId);
// check override flag (see static block)
if("1".equals(sNavBarOverride)) {
hasNav =false;
}elseif("0".equals(sNavBarOverride)) {
hasNav =true;
}
returnhasNav;
}else{// fallback
return!ViewConfiguration.get(context).hasPermanentMenuKey();
}
}
privateintgetInternalDimensionSize(Resources res, String key) {
intresult =0;
intresourceId = res.getIdentifier(key,"dimen","android");
if(resourceId >0) {
result = res.getDimensionPixelSize(resourceId);
}
returnresult;
}
@SuppressLint("NewApi")
privatefloatgetSmallestWidthDp(Activity activity) {
DisplayMetrics metrics =newDisplayMetrics();
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);
}
floatwidthDp = metrics.widthPixels / metrics.density;
floatheightDp = metrics.heightPixels / metrics.density;
returnMath.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.
*/
publicbooleanisNavigationAtBottom() {
return(mSmallestWidthDp >=600|| mInPortrait);
}
/**
* Get the height of the system status bar.
*
* @return The height of the status bar (in pixels).
*/
publicintgetStatusBarHeight() {
returnmStatusBarHeight;
}
/**
* Get the height of the action bar.
*
* @return The height of the action bar (in pixels).
*/
publicintgetActionBarHeight() {
returnmActionBarHeight;
}
/**
* Does this device have a system navigation bar?
*
* @return True if this device uses soft key navigation, False otherwise.
*/
publicbooleanhasNavigtionBar() {
returnmHasNavigationBar;
}
/**
* 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.
*/
publicintgetNavigationBarHeight() {
returnmNavigationBarHeight;
}
/**
* 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.
*/
publicintgetNavigationBarWidth() {
returnmNavigationBarWidth;
}
/**
* Get the layout inset for any system UI that appears at the top of the screen.
*
* @param withActionBar True to include the height of the action bar, False otherwise.
* @return The layout inset (in pixels).
*/
publicintgetPixelInsetTop(booleanwithActionBar) {
return(mTranslucentStatusBar ? mStatusBarHeight :0) + (withActionBar ? mActionBarHeight :0);
}
/**
* Get the layout inset for any system UI that appears at the bottom of the screen.
*
* @return The layout inset (in pixels).
*/
publicintgetPixelInsetBottom() {
if(mTranslucentNavBar && isNavigationAtBottom()) {
returnmNavigationBarHeight;
}else{
return0;
}
}
/**
* Get the layout inset for any system UI that appears at the right of the screen.
*
* @return The layout inset (in pixels).
*/
publicintgetPixelInsetRight() {
if(mTranslucentNavBar && !isNavigationAtBottom()) {
returnmNavigationBarWidth;
}else{
return0;
}
}
}
}
网友评论