当前位置: 移动技术网 > IT编程>移动开发>Android > Android沉浸式状态栏实现

Android沉浸式状态栏实现

2019年07月24日  | 移动技术网IT编程  | 我要评论

赵克石父亲,additionally,超合金战记2.5

苹果上的ui基本上都是这个效果,然而android机上的顶部状态栏总是和app的主题颜色不搭。还好如今的api19以上的版本,我们也能做出这样的效果。

第一步:

  // 需要setcontentview之前调用
  private void settranslucentstatus() {
  if (build.version.sdk_int >= build.version_codes.kitkat) {
    // 透明状态栏
    getwindow().addflags(
        windowmanager.layoutparams.flag_translucent_status);
    // 透明导航栏
    getwindow().addflags(
        windowmanager.layoutparams.flag_translucent_navigation);
          systemstatusmanager tintmanager = new systemstatusmanager(this);
    tintmanager.setstatusbartintenabled(true);
          // 设置状态栏的颜色 
          tintmanager.setstatusbartintresource(r.color.theme_color);
    getwindow().getdecorview().setfitssystemwindows(true);
  }
}

第二步:

为xml 的根布局添加android:fitssystemwindows=”true” 属性

第三步:systemstatusmanager

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;

@suppresswarnings({ “unchecked”, “rawtypes” }) 
public class systemstatusmanager 
{ 
static 
{ 
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 systemstatusmanager(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 {
      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;
    }
  }

}
}

以上就是本文的全部内容,希望大家喜欢。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网