Android4.4实现状态栏沉浸
来源:互联网 发布:网络攻防交流平台 编辑:程序博客网 时间:2024/06/05 02:36
所谓的状态栏沉浸就是要实现一种改变设备的状态栏颜色,从而实现其与我们的app风格一致的效果,属于美化UI的范畴—–by 熊猫卓 20151122
实现
-1.布局
先说布局,要实现状态栏的沉浸效果,首先需要在你的布局文件中加入以下属性
android:clipToPadding="true"android:fitsSystemWindows="true"
关键该属性要加在布局文件最上边的控件中,即距离状态栏最近的控件。在实际博主并不纯熟的使用过程中发现,有的情况下布局文件最外层的控件也要加行这个属性才好使。接下来解释下两个属性的意义
android:clipToPadding=”true”字面意思理解就可以了设置要存在padding。android:fitsSystemWindows=”true”同样字面意思理解即可,调整系统布局适应自己的布局。
-2.Java实现
public static void initSystemBar(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {setTranslucentStatus(activity, true);}SystemBarTintManager tintManager = new SystemBarTintManager(activity);tintManager.setStatusBarTintEnabled(true);// 使用颜色资源tintManager.setStatusBarTintResource(R.color.status_color);}
补充设置状态栏的颜色同样还可以使用
// set a custom tint color for all system bars
tintManager.setTintColor(Color.parseColor(“#99000FF”));
// set a custom navigation bar resource
tintManager.setNavigationBarTintResource(R.drawable.my_tint);
// set a custom status bar drawable
tintManager.setStatusBarTintDrawable(MyDrawable);啰嗦一句,沉浸状态栏的使用必须是基于android adk19及以上版本的,其他版本是没有改效果的。但沉浸也不是随便用的,比如设置了activity全屏模式的时候那么你就没有必要再去设置状态栏颜色了。
下面是工具类来自开元项目
状态栏沉浸
/*
* Copyright (C) 2013 readyState Software Ltd
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.boyuyun.applib;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.graphics.drawable.Drawable;import android.os.Build;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.ViewConfiguration;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 and navigation bar tint effects when using KitKat * translucent system UI modes. * */ public class SystemBarTintManager {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. */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 boolean mNavBarTintEnabled;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 SystemBarTintManager(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. * * 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); }}/** * 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). */public void setNavigationBarTintEnabled(boolean enabled) { 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. */public void setTintColor(int color) { setStatusBarTintColor(color); setNavigationBarTintColor(color);}/** * Apply the specified drawable or color resource to all system UI bars. * * @param res The identifier of the resource. */public void setTintResource(int res) { 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. */public void setTintDrawable(Drawable drawable) { setStatusBarTintDrawable(drawable); setNavigationBarTintDrawable(drawable);}/** * Apply the specified alpha to all system UI bars. * * @param alpha The alpha to use */public void setTintAlpha(float alpha) { setStatusBarAlpha(alpha); setNavigationBarAlpha(alpha);}/** * 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); }}/** * 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")public void setStatusBarTintDrawable(Drawable drawable) { if (mStatusBarAvailable) { mStatusBarTintView.setBackgroundDrawable(drawable); }}/** * Apply the specified alpha to the system status bar. * * @param alpha The alpha to use */@TargetApi(11)public void setStatusBarAlpha(float alpha) { 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. */public void setNavigationBarTintColor(int color) { if (mNavBarAvailable) { mNavBarTintView.setBackgroundColor(color); }}/** * Apply the specified drawable or color resource to the system navigation bar. * * @param res The identifier of the resource. */public void setNavigationBarTintResource(int res) { 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")public void setNavigationBarTintDrawable(Drawable drawable) { if (mNavBarAvailable) { mNavBarTintView.setBackgroundDrawable(drawable); }}/** * Apply the specified alpha to the system navigation bar. * * @param alpha The alpha to use */@TargetApi(11)public void setNavigationBarAlpha(float alpha) { 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. */public SystemBarConfig getConfig() { return mConfig;}/** * Is tinting enabled for the system status bar? * * @return True if enabled, False otherwise. */public boolean isStatusBarTintEnabled() { return mStatusBarTintEnabled;}/** * Is tinting enabled for the system navigation bar? * * @return True if enabled, False otherwise. */public boolean isNavBarTintEnabled() { return mNavBarTintEnabled;}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 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 final boolean mTranslucentStatusBar; private final boolean mTranslucentNavBar; private final int mStatusBarHeight; private final int mActionBarHeight; 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); mActionBarHeight = getActionBarHeight(activity); mNavigationBarHeight = getNavigationBarHeight(activity); mNavigationBarWidth = getNavigationBarWidth(activity); mHasNavigationBar = (mNavigationBarHeight > 0); mTranslucentStatusBar = translucentStatusBar; mTranslucentNavBar = traslucentNavBar; } @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); } /** * 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; } /** * Get the height of the action bar. * * @return The height of the action bar (in pixels). */ public int getActionBarHeight() { return mActionBarHeight; } /** * 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; } /** * 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). */ public int getPixelInsetTop(boolean withActionBar) { 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). */ public int getPixelInsetBottom() { if (mTranslucentNavBar && isNavigationAtBottom()) { return mNavigationBarHeight; } else { return 0; } } /** * Get the layout inset for any system UI that appears at the right of the screen. * * @return The layout inset (in pixels). */ public int getPixelInsetRight() { if (mTranslucentNavBar && !isNavigationAtBottom()) { return mNavigationBarWidth; } else { return 0; } }}}
- Android4.4实现状态栏沉浸
- Android4.4以上实现沉浸式状态栏
- Android4.4 实现沉浸式状态栏
- 实现android4.4新特性:沉浸式状态栏
- 关于Android4.4以后沉浸式自定义状态栏实现
- Android4.4系统以上实现沉浸式状态栏
- 沉浸式状态栏(Android4.4及以上)
- Android4.4 5.0沉浸式状态栏
- Android4.4以上沉浸式状态栏
- Android4.4沉浸状态栏全解析
- android4.4沉浸式状态栏总结
- Android4.4以上实现沉浸式状态栏 及 低版本中使用Material设计
- Android4.4之后实现沉浸式状态栏及虚拟按键的适配
- Android4.4沉浸状态栏 键盘挤压布局受影响
- 实现android4.4沉浸式标题栏
- android4.4~6.0以上沉浸式实现
- Android实现状态栏沉浸
- 沉浸式状态栏实现
- C# 字段
- 大型分布式网站架构设计与实践《概述与大纲》
- Git命令行
- 用Application() 实现同一个程序下数据共享
- 用Hibernate与Struts实现简单的项目的登录与注册
- Android4.4实现状态栏沉浸
- 每天一点matlab——提取图像中的小圆圈
- 三大Javaweb框架的工作原理--Struts2+Hibernate+Spring3
- iOS的二维码扫描
- Android-Material Design布局之第一曲
- 流形学习入门篇1
- 几个bottle插件
- SQL Server之连接
- Java的三种注释 Javadoc标记*