Android自定义手机界面状态栏实例代码

Android自定义手机界面状态栏实例代码,第1张

概述前言我们知道IOS上的应用,状态栏的颜色总能与应用标题栏颜色保持一致,用户体验很不错,那安卓是否可以呢?若是在安卓4.4之前,答案是否定的,但在4.4之后,谷歌允许开发者自定义状态栏背景颜色啦,这是个不错的体

前言

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

实现这个效果有两个方法: 1.在xml中设置主题或自定义style;

theme.Holo.light.NoActionbar.TranslucentDecortheme.Holo.NoActionbar.TranslucentDecor<style name="Apptheme" parent="AppBasetheme"> <!-- Status bar --> <item name="androID:windowTranslucentStatus">true</item> <!-- Navigation bar --> <item name="androID:windowTranslucentNavigation">true</item> </style>

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

2.在代码中控制; 这个情况下可创建一个BaseActivity,在onCreate方法中进行处理:

@OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {   setTranslucentStatus(true);   SystembarTintManager tintManager = new SystembarTintManager(this);   tintManager.setStatusbarTintEnabled(true);   tintManager.setStatusbarTintResource(R.color.top_bg_color);//通知栏所需颜色  }  setContentVIEw(R.layout.main_activity); }  @TargetAPI(19)  private voID setTranslucentStatus(boolean on) {  Window win = getwindow();  WindowManager.LayoutParams winParams = win.getAttributes();  final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;  if (on) {   winParams.flags |= bits;  } else {   winParams.flags &= ~bits;  }  win.setAttributes(winParams);  }

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

SystembarTintManager.java源码代码:/* * 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.zhjy.hxf.hzsmallmi.util;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;  } } }}

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

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

这样就达到了咱们最开始的样式。

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方法中加了几句代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {  ((linearLayout)findVIEwByID(R.ID.ll)).setpadding(0,SysUtils.getStatusHeight(this),0);  }

意思是,先求出状态栏高度,然后设置最外层控件的paddingtop值为状态栏高度,结果正好达到效果,至于为什么只有首页Activity可以达到效果,而后面的子项无法达到效果,本人也在郁闷中,有知道的朋友可以分享下! 状态栏高度算法:

/**   * 状态栏高度算法   * @param activity   * @return   */  public static int getStatusHeight(Activity activity){   int statusHeight = 0;   Rect localRect = new Rect();   activity.getwindow().getDecorVIEw().getwindowVisibledisplayFrame(localRect);   statusHeight = localRect.top;   if (0 == statusHeight){   Class<?> localClass;   try {    localClass = Class.forname("com.androID.internal.R$dimen");    Object localObject = localClass.newInstance();    int i5 = Integer.parseInt(localClass.getFIEld("status_bar_height").get(localObject).toString());    statusHeight = activity.getResources().getDimensionPixelSize(i5);   } catch (ClassNotFoundException e) {    e.printstacktrace();   } catch (illegalaccessexception e) {    e.printstacktrace();   } catch (InstantiationException e) {    e.printstacktrace();   } catch (NumberFormatException e) {    e.printstacktrace();   } catch (IllegalArgumentException e) {    e.printstacktrace();   } catch (SecurityException e) {    e.printstacktrace();   } catch (NoSuchFIEldException e) {    e.printstacktrace();   }   }   return statusHeight;  }

以上所述是小编给大家介绍的AndroID自定义手机界面状态栏实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android自定义手机界面状态栏实例代码全部内容,希望文章能够帮你解决Android自定义手机界面状态栏实例代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1146752.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存