Android沉浸式通知栏开源库SystemBarTint源码解析

来源:互联网 发布:淘宝网儿童玩具 编辑:程序博客网 时间:2024/05/21 22:34

前一段时间我写了一篇关于沉浸式的文章: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);        }
0 0
原创粉丝点击