android自定义状态栏颜色

简介: 我们知道IOS上的应用,状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,那安卓是否可以呢?若是在安卓4.4之前,答案是否定的,但在4.4之后,谷歌允许开发者自定义状态栏背景颜色啦,这是个不错的体验!若你手机上安装有最新版的qq,并且你的安卓SDK版本是4.4及以上,你可以看下它的效果: 实现此功能有两种方法: 1.在xml中设置主题或自定义style;

我们知道IOS上的应用,状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,那安卓是否可以呢?若是在安卓4.4之前,答案是否定的,但在4.4之后,谷歌允许开发者自定义状态栏背景颜色啦,这是个不错的体验!若你手机上安装有最新版的qq,并且你的安卓SDK版本是4.4及以上,你可以看下它的效果:


实现此功能有两种方法:

1.在xml中设置主题或自定义style;

[html]  view plain copy
  1. Theme.Holo.Light.NoActionBar.TranslucentDecor  

[html]  view plain copy
  1. Theme.Holo.NoActionBar.TranslucentDecor  

[html]  view plain copy
  1. <style name="AppTheme" parent="AppBaseTheme">  
  2. <!-- Status Bar -->  
  3. <item name="android:windowTranslucentStatus">true</item>  
  4. <!-- Navigation Bar -->  
  5. <item name="android:windowTranslucentNavigation">true</item>  
  6. </style>  

鉴于市面上各种手机的SDK的各种版本,不建议采用这种方法;


2.在代码中控制;

可以首先创建一个BaseActivity,在onCreate方法中进行处理:

[html]  view plain copy
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    
  5.            setTranslucentStatus(true);    
  6.            SystemBarTintManager tintManager = new SystemBarTintManager(this);    
  7.            tintManager.setStatusBarTintEnabled(true);    
  8.            tintManager.setStatusBarTintResource(R.color.top_bg_color);//通知栏所需颜色  
  9.        }    
  10.     setContentView(R.layout.main_activity);  
  11. }  
  12.   
  13. @TargetApi(19)     
  14.    private void setTranslucentStatus(boolean on) {    
  15.        Window win = getWindow();    
  16.        WindowManager.LayoutParams winParams = win.getAttributes();    
  17.        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;    
  18.        if (on) {    
  19.            winParams.flags |= bits;    
  20.        } else {    
  21.            winParams.flags &= ~bits;    
  22.        }    
  23.        win.setAttributes(winParams);    
  24.    }  


需注意的是, tintManager.setStatusBarTintResource(R.color.top_bg_color);这一步的颜色值(即把你的状态栏颜色与你的标题栏颜色保持一致)要写在color.xml中去,如果用Color.praseColor则会报错。

SystemBarTintManager.java源码:

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

代码复制进你的项目即可,好了,这些工作完成之后我们来看下效果:


貌似已经达到效果了,但仔细观察,好像标题栏被提上去了,就是说APP界面全屏了,状态了盖在了APP上,恩,这并非我们想要的效果,那如何将界面从状态栏下部开始呢,只需要在Activity的布局文件最外层控件加上一个属性:

 android:fitsSystemWindows="true"就可以啦!看下效果:


OK,大功告成!


PS:在使用过程中发现了一些问题,使用以上方法对单个Activity有效,但是对继承了TabActivity的导航页怎么办呢?假如MainActivity继承了TabActivity,Tab1Activity、Tab2Activity、Tab3Activity是三个子项,那么设置状态栏的代码需写在MainActivity中,而 android:fitsSystemWindows="true"需写在三个子Activity的xml布局文件中,这样设置后仍然有问题,就是进入应用后首页也就是Tab1Activity没有问题,而Tab2Activity、Tab3Activity却没达到效果,它们的效果相当于未加android:fitsSystemWindows="true"时的效果,期初我怀疑是Activity不同的原因,因此我把Tab1Activity和Tab3Activity调了下位置,结果Tab3Activity成为首页后正常,而Tab1Activity又不正常了,百思不得姐,最后实在没办法,就在Tab2Activity、Tab3Activity的OnCreate方法中加了几句代码:

[html]  view plain copy
  1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  
  2.        ((LinearLayout)findViewById(R.id.ll)).setPadding(0, SysUtils.getStatusHeight(this), 0,0);  
  3.    }  
意思是,先求出状态栏高度,然后设置最外层控件的PaddingTop值为状态栏高度,结果正好达到效果,至于为什么只有首页Activity可以达到效果,而后面的子项无法达到效果,本人也在郁闷中,有知道的朋友可以分享下!

状态栏高度算法:

[html]  view plain copy
  1. /**  
  2.          * 状态栏高度算法  
  3.          * @param activity  
  4.          * @return  
  5.          */  
  6.         public static int getStatusHeight(Activity activity){    
  7.             int statusHeight = 0;    
  8.             Rect localRect = new Rect();    
  9.             activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);    
  10.             statusHeight = localRect.top;    
  11.             if (0 == statusHeight){    
  12.                 Class<?> localClass;    
  13.                 try {    
  14.                     localClass = Class.forName("com.android.internal.R$dimen");    
  15.                     Object localObject = localClass.newInstance();    
  16.                     int i5 = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString());    
  17.                     statusHeight = activity.getResources().getDimensionPixelSize(i5);    
  18.                 } catch (ClassNotFoundException e) {    
  19.                     e.printStackTrace();    
  20.                 } catch (IllegalAccessException e) {    
  21.                     e.printStackTrace();    
  22.                 } catch (InstantiationException e) {    
  23.                     e.printStackTrace();    
  24.                 } catch (NumberFormatException e) {    
  25.                     e.printStackTrace();    
  26.                 } catch (IllegalArgumentException e) {    
  27.                     e.printStackTrace();    
  28.                 } catch (SecurityException e) {    
  29.                     e.printStackTrace();    
  30.                 } catch (NoSuchFieldException e) {    
  31.                     e.printStackTrace();    
  32.                 }    
  33.             }    
  34.             return statusHeight;    
  35.         }    
目录
相关文章
|
26天前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
23 1
|
2月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
42 3
|
2月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
93 0
|
1月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
1月前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
36 5
|
2月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
3月前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
67 10
|
3月前
|
XML 编解码 Android开发
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
55 3
|
3月前
|
前端开发 Android开发 开发者
安卓应用开发中的自定义视图基础
【9月更文挑战第13天】在安卓开发的广阔天地中,自定义视图是一块神奇的画布,它允许开发者将想象力转化为用户界面的创新元素。本文将带你一探究竟,了解如何从零开始构建自定义视图,包括绘图基础、触摸事件处理,以及性能优化的实用技巧。无论你是想提升应用的视觉吸引力,还是追求更流畅的交互体验,这里都有你需要的金钥匙。
|
3月前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。