欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 沉浸式改变小米魅族状态栏颜色的实例代码

程序员文章站 2023-12-19 19:50:22
这个是基于systembartintmanager更改的 增加一个方法:用于更改miuiv6系统上的状态栏字体颜色 ,目前我仅仅只发现miuiv6上可以更改,在andro...

这个是基于systembartintmanager更改的

增加一个方法:用于更改miuiv6系统上的状态栏字体颜色 ,目前我仅仅只发现miuiv6上可以更改,在android5.0上以及其它4.4以上系统没有发现可以更改字体颜色的代码

核心代码:   

 public void setstatusbardarkmode(boolean darkmode, activity activity) { 
  if (sismiuiv6) { 
   class<? extends window> clazz = activity.getwindow().getclass(); 
   try { 
   int darkmodeflag = 0; 
   class<?> layoutparams = class.forname("android.view.miuiwindowmanager$layoutparams"); 
   field field = layoutparams.getfield("extra_flag_status_bar_dark_mode"); 
   darkmodeflag = field.getint(layoutparams); 
   method extraflagfield = clazz.getmethod("setextraflags", int.class, int.class); 
   extraflagfield.invoke(activity.getwindow(), darkmode ? darkmodeflag : 0, darkmodeflag); 
   } catch (exception e) { 
   e.printstacktrace(); 
   } 
  } 
 } 

全部代码:

 /* 
 * 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. 
 */ 
 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.field; 
 import java.lang.reflect.method; 
 /** 
 * class to manage status and navigation bar tint effects when using kitkat 
 * translucent system ui modes. 
 * 
 */ 
 public class systembartintmanager { 
 /** 
  * 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; 
 private static boolean sismiuiv6; 
 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); 
   sismiuiv6 = "v6".equals((string) m.invoke(c, "ro.miui.ui.version.name")); 
   snavbaroverride = (string) m.invoke(null, "qemu.hw.mainkeys"); 
  } catch (throwable e) { 
   snavbaroverride = null; 
  } 
  } 
 } 
 /** 
  * 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; 
  } 
  } 
 } 
 public void setstatusbardarkmode(boolean darkmode, activity activity) { 
  if (sismiuiv6) { 
   class<? extends window> clazz = activity.getwindow().getclass(); 
   try { 
   int darkmodeflag = 0; 
   class<?> layoutparams = class.forname("android.view.miuiwindowmanager$layoutparams"); 
   field field = layoutparams.getfield("extra_flag_status_bar_dark_mode"); 
   darkmodeflag = field.getint(layoutparams); 
   method extraflagfield = clazz.getmethod("setextraflags", int.class, int.class); 
   extraflagfield.invoke(activity.getwindow(), darkmode ? darkmodeflag : 0, darkmodeflag); 
   } catch (exception e) { 
   e.printstacktrace(); 
   } 
  } 
 } 
 } 

用法: 

 public void initsystembar(){ 
  if (version.sdk_int >= version_codes.kitkat) { 
  getwindow().addflags(windowmanager.layoutparams.flag_translucent_status); 
  getwindow().addflags(windowmanager.layoutparams.flag_translucent_navigation); 
  getwindow().addflags(windowmanager.layoutparams.flag_draws_system_bar_backgrounds); 
  fwrootlayout.setfitssystemwindows(true);//需要把根布局设置为这个属性 子布局则不会占用状态栏位置 
  fwrootlayout.setcliptopadding(true);//需要把根布局设置为这个属性 子布局则不会占用状态栏位置 
  } 
  tintmanager = new systembartintmanager(this);// 创建状态栏的管理实例 
  tintmanager.setstatusbartintenabled(true);// 激活状态栏设置 
  tintmanager.setnavigationbartintenabled(true);// 激活导航栏设置 
  tintmanager.setstatusbartintcolor(getresources().getcolor(r.color.blue500));//设置状态栏颜色 
  tintmanager.setstatusbardarkmode(false, this);//false 状态栏字体颜色是白色 true 颜色是黑色 
 } 

截图

Android 沉浸式改变小米魅族状态栏颜色的实例代码 
Android 沉浸式改变小米魅族状态栏颜色的实例代码

以上所述是小编给大家介绍的android 沉浸式改变小米魅族状态栏颜色的实例代码,希望对大家有所帮助

上一篇:

下一篇: