博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
另外一种设置沉浸式标题栏的方式
阅读量:4595 次
发布时间:2019-06-09

本文共 23056 字,大约阅读时间需要 76 分钟。

今天又看到了另外一种设置沉浸式标题栏的方式,比上次写的那个使用主题,设置主题背景色的要好很多了。尤其是设置主题背景色后,程序从后台到前台ui界面没加载出来会显示出短暂的标题栏的颜色,因此设置主题背景颜色的方式还是有些缺陷。

废话不多说,我介绍的这个方法使用了小米的一个类:SystemBarTintManager

小米官网的地址 http://dev.xiaomi.com/doc/p=4769/index.html

经过测试在其他的手机上一样适用,只是那个设置标题栏字体颜色为黑色不能用而已。

1 /*  2  * Copyright (C) 2013 readyState Software Ltd  3  *  4  * Licensed under the Apache License, Version 2.0 (the "License");  5  * you may not use this file except in compliance with the License.  6  * You may obtain a copy of the License at  7  *  8  *      http://www.apache.org/licenses/LICENSE-2.0  9  * 10  * Unless required by applicable law or agreed to in writing, software 11  * distributed under the License is distributed on an "AS IS" BASIS, 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13  * See the License for the specific language governing permissions and 14  * limitations under the License. 15  */ 16  17 package com.readystatesoftware.systembartint; 18  19 import java.lang.reflect.Field; 20 import java.lang.reflect.Method; 21  22 import android.annotation.SuppressLint; 23 import android.annotation.TargetApi; 24 import android.app.Activity; 25 import android.content.Context; 26 import android.content.res.Configuration; 27 import android.content.res.Resources; 28 import android.content.res.TypedArray; 29 import android.graphics.drawable.Drawable; 30 import android.os.Build; 31 import android.util.DisplayMetrics; 32 import android.util.TypedValue; 33 import android.view.Gravity; 34 import android.view.View; 35 import android.view.ViewConfiguration; 36 import android.view.ViewGroup; 37 import android.view.Window; 38 import android.view.WindowManager; 39 import android.widget.FrameLayout.LayoutParams; 40  41 /** 42  * Class to manage status and navigation bar tint effects when using KitKat 43  * translucent system UI modes. 44  * 45  */ 46 public class SystemBarTintManager { 47  48     /** 49      * The default system bar tint color value. 50      */ 51     public static final int DEFAULT_TINT_COLOR = 0x99000000; 52  53     private final SystemBarConfig mConfig; 54     private boolean mStatusBarAvailable; 55     private boolean mNavBarAvailable; 56     private boolean mStatusBarTintEnabled; 57     private boolean mNavBarTintEnabled; 58     private View mStatusBarTintView; 59     private View mNavBarTintView; 60     private static boolean sIsMiuiV6; 61  62     static { 63         try { 64             Class
sysClass = Class.forName("android.os.SystemProperties"); 65 Method getStringMethod = sysClass.getDeclaredMethod("get", String.class); 66 sIsMiuiV6 = "V6".equals((String) getStringMethod.invoke(sysClass, "ro.miui.ui.version.name")); 67 } catch (Exception e) { 68 e.printStackTrace(); 69 } 70 } 71 72 /** 73 * Constructor. Call this in the host activity onCreate method after its 74 * content view has been set. You should always create new instances when 75 * the host activity is recreated. 76 * 77 * @param activity The host activity. 78 */ 79 @TargetApi(19) 80 public SystemBarTintManager(Activity activity) { 81 82 Window win = activity.getWindow(); 83 ViewGroup decorViewGroup = (ViewGroup) win.getDecorView(); 84 85 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 86 // check theme attrs 87 int[] attrs = {android.R.attr.windowTranslucentStatus, 88 android.R.attr.windowTranslucentNavigation}; 89 TypedArray a = activity.obtainStyledAttributes(attrs); 90 try { 91 mStatusBarAvailable = a.getBoolean(0, false); 92 mNavBarAvailable = a.getBoolean(1, false); 93 } finally { 94 a.recycle(); 95 } 96 97 // check window flags 98 WindowManager.LayoutParams winParams = win.getAttributes(); 99 int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;100 if ((winParams.flags & bits) != 0) {101 mStatusBarAvailable = true;102 }103 bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;104 if ((winParams.flags & bits) != 0) {105 mNavBarAvailable = true;106 }107 }108 109 mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);110 // device might not have virtual navigation keys111 if (!mConfig.hasNavigtionBar()) {112 mNavBarAvailable = false;113 }114 115 if (mStatusBarAvailable) {116 setupStatusBarView(activity, decorViewGroup);117 }118 if (mNavBarAvailable) {119 setupNavBarView(activity, decorViewGroup);120 }121 122 }123 124 /**125 * Enable tinting of the system status bar.126 *127 * If the platform is running Jelly Bean or earlier, or translucent system128 * UI modes have not been enabled in either the theme or via window flags,129 * then this method does nothing.130 *131 * @param enabled True to enable tinting, false to disable it (default).132 */133 public void setStatusBarTintEnabled(boolean enabled) {134 mStatusBarTintEnabled = enabled;135 if (mStatusBarAvailable) {136 mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);137 }138 }139 140 /**141 * set status bar darkmode142 * @param darkmode143 * @param activity144 */145 public void setStatusBarDarkMode(boolean darkmode, Activity activity) {146 if (sIsMiuiV6) {147 Class
clazz = activity.getWindow().getClass();148 try {149 int darkModeFlag = 0;150 Class
layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");151 Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");152 darkModeFlag = field.getInt(layoutParams);153 Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);154 extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);155 } catch (Exception e) {156 e.printStackTrace();157 }158 }159 }160 161 /**162 * Enable tinting of the system navigation bar.163 *164 * If the platform does not have soft navigation keys, is running Jelly Bean165 * or earlier, or translucent system UI modes have not been enabled in either166 * the theme or via window flags, then this method does nothing.167 *168 * @param enabled True to enable tinting, false to disable it (default).169 */170 public void setNavigationBarTintEnabled(boolean enabled) {171 mNavBarTintEnabled = enabled;172 if (mNavBarAvailable) {173 mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);174 }175 }176 177 /**178 * Apply the specified color tint to all system UI bars.179 *180 * @param color The color of the background tint.181 */182 public void setTintColor(int color) {183 setStatusBarTintColor(color);184 setNavigationBarTintColor(color);185 }186 187 /**188 * Apply the specified drawable or color resource to all system UI bars.189 *190 * @param res The identifier of the resource.191 */192 public void setTintResource(int res) {193 setStatusBarTintResource(res);194 setNavigationBarTintResource(res);195 }196 197 /**198 * Apply the specified drawable to all system UI bars.199 *200 * @param drawable The drawable to use as the background, or null to remove it.201 */202 public void setTintDrawable(Drawable drawable) {203 setStatusBarTintDrawable(drawable);204 setNavigationBarTintDrawable(drawable);205 }206 207 /**208 * Apply the specified alpha to all system UI bars.209 *210 * @param alpha The alpha to use211 */212 public void setTintAlpha(float alpha) {213 setStatusBarAlpha(alpha);214 setNavigationBarAlpha(alpha);215 }216 217 /**218 * Apply the specified color tint to the system status bar.219 *220 * @param color The color of the background tint.221 */222 public void setStatusBarTintColor(int color) {223 if (mStatusBarAvailable) {224 mStatusBarTintView.setBackgroundColor(color);225 }226 }227 228 /**229 * Apply the specified drawable or color resource to the system status bar.230 *231 * @param res The identifier of the resource.232 */233 public void setStatusBarTintResource(int res) {234 if (mStatusBarAvailable) {235 mStatusBarTintView.setBackgroundResource(res);236 }237 }238 239 /**240 * Apply the specified drawable to the system status bar.241 *242 * @param drawable The drawable to use as the background, or null to remove it.243 */244 @SuppressWarnings("deprecation")245 public void setStatusBarTintDrawable(Drawable drawable) {246 if (mStatusBarAvailable) {247 mStatusBarTintView.setBackgroundDrawable(drawable);248 }249 }250 251 /**252 * Apply the specified alpha to the system status bar.253 *254 * @param alpha The alpha to use255 */256 @TargetApi(11)257 public void setStatusBarAlpha(float alpha) {258 if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {259 mStatusBarTintView.setAlpha(alpha);260 }261 }262 263 /**264 * Apply the specified color tint to the system navigation bar.265 *266 * @param color The color of the background tint.267 */268 public void setNavigationBarTintColor(int color) {269 if (mNavBarAvailable) {270 mNavBarTintView.setBackgroundColor(color);271 }272 }273 274 /**275 * Apply the specified drawable or color resource to the system navigation bar.276 *277 * @param res The identifier of the resource.278 */279 public void setNavigationBarTintResource(int res) {280 if (mNavBarAvailable) {281 mNavBarTintView.setBackgroundResource(res);282 }283 }284 285 /**286 * Apply the specified drawable to the system navigation bar.287 *288 * @param drawable The drawable to use as the background, or null to remove it.289 */290 @SuppressWarnings("deprecation")291 public void setNavigationBarTintDrawable(Drawable drawable) {292 if (mNavBarAvailable) {293 mNavBarTintView.setBackgroundDrawable(drawable);294 }295 }296 297 /**298 * Apply the specified alpha to the system navigation bar.299 *300 * @param alpha The alpha to use301 */302 @TargetApi(11)303 public void setNavigationBarAlpha(float alpha) {304 if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {305 mNavBarTintView.setAlpha(alpha);306 }307 }308 309 /**310 * Get the system bar configuration.311 *312 * @return The system bar configuration for the current device configuration.313 */314 public SystemBarConfig getConfig() {315 return mConfig;316 }317 318 /**319 * Is tinting enabled for the system status bar?320 *321 * @return True if enabled, False otherwise.322 */323 public boolean isStatusBarTintEnabled() {324 return mStatusBarTintEnabled;325 }326 327 /**328 * Is tinting enabled for the system navigation bar?329 *330 * @return True if enabled, False otherwise.331 */332 public boolean isNavBarTintEnabled() {333 return mNavBarTintEnabled;334 }335 336 private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {337 mStatusBarTintView = new View(context);338 LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());339 params.gravity = Gravity.TOP;340 if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {341 params.rightMargin = mConfig.getNavigationBarWidth();342 }343 mStatusBarTintView.setLayoutParams(params);344 mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);345 mStatusBarTintView.setVisibility(View.GONE);346 decorViewGroup.addView(mStatusBarTintView);347 }348 349 private void setupNavBarView(Context context, ViewGroup decorViewGroup) {350 mNavBarTintView = new View(context);351 LayoutParams params;352 if (mConfig.isNavigationAtBottom()) {353 params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());354 params.gravity = Gravity.BOTTOM;355 } else {356 params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);357 params.gravity = Gravity.RIGHT;358 }359 mNavBarTintView.setLayoutParams(params);360 mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);361 mNavBarTintView.setVisibility(View.GONE);362 decorViewGroup.addView(mNavBarTintView);363 }364 365 /**366 * Class which describes system bar sizing and other characteristics for the current367 * device configuration.368 *369 */370 public static class SystemBarConfig {371 372 private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";373 private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";374 private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";375 private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";376 377 private final boolean mTranslucentStatusBar;378 private final boolean mTranslucentNavBar;379 private final int mStatusBarHeight;380 private final int mActionBarHeight;381 private final boolean mHasNavigationBar;382 private final int mNavigationBarHeight;383 private final int mNavigationBarWidth;384 private final boolean mInPortrait;385 private final float mSmallestWidthDp;386 387 private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {388 Resources res = activity.getResources();389 mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);390 mSmallestWidthDp = getSmallestWidthDp(activity);391 mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);392 mActionBarHeight = getActionBarHeight(activity);393 mNavigationBarHeight = getNavigationBarHeight(activity);394 mNavigationBarWidth = getNavigationBarWidth(activity);395 mHasNavigationBar = (mNavigationBarHeight > 0);396 mTranslucentStatusBar = translucentStatusBar;397 mTranslucentNavBar = traslucentNavBar;398 }399 400 @TargetApi(14)401 private int getActionBarHeight(Context context) {402 int result = 0;403 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {404 TypedValue tv = new TypedValue();405 context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);406 result = context.getResources().getDimensionPixelSize(tv.resourceId);407 }408 return result;409 }410 411 @TargetApi(14)412 private int getNavigationBarHeight(Context context) {413 Resources res = context.getResources();414 int result = 0;415 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {416 if (!ViewConfiguration.get(context).hasPermanentMenuKey()) {417 String key;418 if (mInPortrait) {419 key = NAV_BAR_HEIGHT_RES_NAME;420 } else {421 key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;422 }423 return getInternalDimensionSize(res, key);424 }425 }426 return result;427 }428 429 @TargetApi(14)430 private int getNavigationBarWidth(Context context) {431 Resources res = context.getResources();432 int result = 0;433 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {434 if (!ViewConfiguration.get(context).hasPermanentMenuKey()) {435 return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);436 }437 }438 return result;439 }440 441 private int getInternalDimensionSize(Resources res, String key) {442 int result = 0;443 int resourceId = res.getIdentifier(key, "dimen", "android");444 if (resourceId > 0) {445 result = res.getDimensionPixelSize(resourceId);446 }447 return result;448 }449 450 @SuppressLint("NewApi")451 private float getSmallestWidthDp(Activity activity) {452 DisplayMetrics metrics = new DisplayMetrics();453 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {454 activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);455 } else {456 // TODO this is not correct, but we don't really care pre-kitkat457 activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);458 }459 float widthDp = metrics.widthPixels / metrics.density;460 float heightDp = metrics.heightPixels / metrics.density;461 return Math.min(widthDp, heightDp);462 }463 464 /**465 * Should a navigation bar appear at the bottom of the screen in the current466 * device configuration? A navigation bar may appear on the right side of467 * the screen in certain configurations.468 *469 * @return True if navigation should appear at the bottom of the screen, False otherwise.470 */471 public boolean isNavigationAtBottom() {472 return (mSmallestWidthDp >= 600 || mInPortrait);473 }474 475 /**476 * Get the height of the system status bar.477 *478 * @return The height of the status bar (in pixels).479 */480 public int getStatusBarHeight() {481 return mStatusBarHeight;482 }483 484 /**485 * Get the height of the action bar.486 *487 * @return The height of the action bar (in pixels).488 */489 public int getActionBarHeight() {490 return mActionBarHeight;491 }492 493 /**494 * Does this device have a system navigation bar?495 *496 * @return True if this device uses soft key navigation, False otherwise.497 */498 public boolean hasNavigtionBar() {499 return mHasNavigationBar;500 }501 502 /**503 * Get the height of the system navigation bar.504 *505 * @return The height of the navigation bar (in pixels). If the device does not have506 * soft navigation keys, this will always return 0.507 */508 public int getNavigationBarHeight() {509 return mNavigationBarHeight;510 }511 512 /**513 * Get the width of the system navigation bar when it is placed vertically on the screen.514 *515 * @return The width of the navigation bar (in pixels). If the device does not have516 * soft navigation keys, this will always return 0.517 */518 public int getNavigationBarWidth() {519 return mNavigationBarWidth;520 }521 522 /**523 * Get the layout inset for any system UI that appears at the top of the screen.524 *525 * @param withActionBar True to include the height of the action bar, False otherwise.526 * @return The layout inset (in pixels).527 */528 public int getPixelInsetTop(boolean withActionBar) {529 return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);530 }531 532 /**533 * Get the layout inset for any system UI that appears at the bottom of the screen.534 *535 * @return The layout inset (in pixels).536 */537 public int getPixelInsetBottom() {538 if (mTranslucentNavBar && isNavigationAtBottom()) {539 return mNavigationBarHeight;540 } else {541 return 0;542 }543 }544 545 /**546 * Get the layout inset for any system UI that appears at the right of the screen.547 *548 * @return The layout inset (in pixels).549 */550 public int getPixelInsetRight() {551 if (mTranslucentNavBar && !isNavigationAtBottom()) {552 return mNavigationBarWidth;553 } else {554 return 0;555 }556 }557 558 }559 560 }

使用起来也很简单,在你的activity或者baseactivity的oncreate方法中加入以下代码:

1 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {2             setTranslucentStatus(true);3         }4         mTintManager = new SystemBarTintManager(this);5         mTintManager.setStatusBarTintEnabled(true);6         //使StatusBarTintView 和 actionbar的颜色保持一致,风格统一。7         mTintManager.setStatusBarTintResource(R.color.navbar);8         // 设置状态栏的文字颜色9         mTintManager.setStatusBarDarkMode(false, this);

setTranslucentStatus方法

1 @TargetApi(19) 2     protected void setTranslucentStatus(boolean on) { 3         Window win = getWindow(); 4         WindowManager.LayoutParams winParams = win.getAttributes(); 5         final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; 6         if (on) { 7             winParams.flags |= bits; 8         } else { 9             winParams.flags &= ~bits;10         }11         win.setAttributes(winParams);12     }

然后需要在你的布局文件最外层添加以下代码

 1 android:fitsSystemWindows="true"

2 android:clipToPadding="false" 这个在设置主题的那里是设置为true的,注意区分

如果你只用了普通的activity,那么一切事情都已经结束了。但我做的司信项目,在主界面上用的是一个activitygroup,然后用tabhost添加了4个activity,这样的话会有一些出入,需要在activitygroup的方法上写上以上代码,activity继承了baseactivity,因此也加入了这些属性,会造成自定义的导航栏文字显示不全。

这个时候就再调用一下

mTintManager.setStatusBarTintEnabled(false);//把自定义的titlebar设置不显示 这样就可以了,效果是与之前的一样的,因此不再贴图。好处就是不会忽然闪一下之前的红色背景了。

转载于:https://www.cnblogs.com/dongweiq/p/4448074.html

你可能感兴趣的文章
一本通1626【例 2】Hankson 的趣味题
查看>>
UImage类方法和构造方法的缓存区别
查看>>
[C++基础]031_如何正确获取用户的输入
查看>>
插入排序
查看>>
DecimalFormat 中的 # 与 0 的区别(中文帮助文档中翻译可能是错误的)
查看>>
BZOJ 2754 【SCOI2012】 喵星球上的点名
查看>>
[leetcode] 49. 字母异位词分组
查看>>
183. Customers Who Never Order--solution
查看>>
贝叶斯如何生效
查看>>
UVA - 1588 - Kickdown
查看>>
Win32 SDK:ListBox 为什么不整个 LB_SETTEXT
查看>>
spring的优缺点
查看>>
优云老王的心路历程(一):那个做了五年的产品经理
查看>>
双态运维分享之:业务场景驱动的服务型CMDB
查看>>
cocos2dx-3.6 触摸,键盘,聚焦事件
查看>>
JEECG中t:dictSelect的extendJson用法
查看>>
web开发下的各种下载方法
查看>>
第六章 堆排序 6.5 优先队列
查看>>
Linux搭建我的世界服务器
查看>>
数据库之范式
查看>>