前一段时间我写了一篇关于沉浸式的文章:Android实现沉浸式状态栏的那些坑
当时只是知道SystemBarTint的存在,并没有去了解它的实现效果和原理,因为搜Android沉浸式时好多都提到这个开源库,还以为很强大、很深奥,就没敢仓促的去看源码。今天把SystemBarTint拉下来一看,发现这个库仅仅只有一个类:SystemBarTintManager,全篇通读下来发现原理也是相当简单:就是在状态栏填充一个指定颜色、与状态栏等高的view

    private void setupStatusBarView(Activity activity) {        Window win = activity.getWindow();        ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();//拿到decorview                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);        // 将纯色的StatusBarTintView添加到decorview        decorViewGroup.addView(mStatusBarTintView);    }

稍微修改了一点源码,便于理解。导航栏的实现也是一样的。

这样看来,这个库仅仅是用view填充状态栏,虽然可以设置颜色、drawable,但是跟有些需求还是有出入的,所以还是可以看看另一种方案:让view延伸到状态栏,然后设置状态栏等高的padding。
可以参考http://blog.csdn.net/brian512/article/details/52096445

SystemBarTint里面对于状态栏和导航栏高度的获取方法还是可以学习一下的,那么多人用过没问题,应该算是适配不错的:

        private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";        private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";        private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";        private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";        private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";                   private int getStatusBarHeightHeight(Context context) {            return getInternalDimensionSize(context.getResources(), STATUS_BAR_HEIGHT_RES_NAME);        }        @TargetApi(14)        private int getActionBarHeight(Context context) {            int result = 0;            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {                TypedValue tv = new TypedValue();                context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);                result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());            }            return result;        }        @TargetApi(14)        private int getNavigationBarHeight(Context context) {            Resources res = context.getResources();            int result = 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;                    }                    return getInternalDimensionSize(res, key);                }            }            return result;        }        @TargetApi(14)        private int getNavigationBarWidth(Context context) {            Resources res = context.getResources();            int result = 0;            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {                if (hasNavBar(context)) {                    return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);                }            }            return result;        }        @TargetApi(14)        private boolean hasNavBar(Context context) {            Resources res = context.getResources();            int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");            if (resourceId != 0) {                boolean hasNav = res.getBoolean(resourceId);                // check override flag (see static block)                if ("1".equals(sNavBarOverride)) {                    hasNav = false;                } else if ("0".equals(sNavBarOverride)) {                    hasNav = true;                }                return hasNav;            } else { // fallback                return !ViewConfiguration.get(context).hasPermanentMenuKey();            }        }        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);        }

更多相关文章

  1. Android(安卓)4.0 framework源码修改编译,模拟器运行不起来——解
  2. Android中直播视频技术探究之---视频直播服务端环境搭建(Nginx+R
  3. 自定义ListView背景(解决了拖动变黑的效果)
  4. Android(安卓)源码中的设计模式
  5. Android(安卓)实战 (一) Remote Service,Thread,Handler,Broadcast
  6. Android(安卓)源码本地编译脚本 & 编译Android系统
  7. Android(安卓)9 (P)之init进程启动源码分析指南之三
  8. Android(安卓)JSBridge的原理与实现
  9. android简易画图板与五子棋

随机推荐

  1. mac下搭建android sdk
  2. Webkit for Android分析
  3. Android(安卓)Studio/IntelliJIDEA 快捷
  4. 设计师 DPI 参考指南
  5. Android(安卓)3d 球形建模
  6. 使用PreferenceActivity设置应用程序参数
  7. Android有效解决加载大图片时内存溢出的
  8. Android布局和intent实例
  9. Android课程---Android(安卓)Studio安装
  10. Android(安卓)通用获取Ip的方法(判断手机