Home>

Foreword:

Android development, for the modification of the status bar,Really unfriendly,No api is available, not as convenient as ios.But ui likes to only engage in a set of ios. No way. Various source code,Write reflection. It really hurts.

Demand scenario:

I. Modify the status bar color:

Change the status bar color,Have a look at this article.Portal:Realizing the status bar gradient effect is actually very simple

Effects achieved by the portal:

The color of the status bar achieved by this method,No black background.

The effect achieved using the full screen mode is as follows (the effect of qq):

Obvious black background.

My phone is Huawei.System 7.0

Modify the status bar font:

General tools:

public class statusbarutil {
  /**
   * Set the black font icon in the status bar,   * Compatible with Miuiv 4.4, Flyme and other Android versions 6.0 and above
   *
   * @return 1:miuui 2:flyme 3:android6.0
   * /
  public static int getstatusbarlightmode (window window) {
    int result=0;
    if (build.version.sdk_int>= build.version_codes.kitkat) {
      if (miuisetstatusbarlightmode (window, true)) {
        result=1;
      } else if (flymesetstatusbarlightmode (window, true)) {
        result=2;
      } else if (build.version.sdk_int>= build.version_codes.m) {
        window.getdecorview (). setsystemuivisibility (view.system_ui_flag_light_status_bar);
        result=3;
      } else {//5.0
      }
    }
    return result;
  }
  /**
   * When the system type is known,Set the status bar black font icon.
   * Compatible with Miuiv 4.4, Flyme and other Android versions 6.0 and above
   * /
  public static void setstatusbarlightmode (window window) {
    int type=getstatusbarlightmode (window);
    if (type == 1) {
      miuisetstatusbarlightmode (window, true);
    } else if (type == 2) {
      flymesetstatusbarlightmode (window, true);
    } else if (type == 3) {
      window.getdecorview (). setsystemuivisibility (view.system_ui_flag_light_status_bar);
    } else {//5.0
    }
  }
  /**
   * Clear the black font in the status bar of miui or flyme or above 6.0
   * /
  public static void statusbardarkmode (window window) {
    int type=getstatusbarlightmode (window);
    if (type == 1) {
      miuisetstatusbarlightmode (window, false);
    } else if (type == 2) {
      flymesetstatusbarlightmode (window, false);
    } else if (type == 3) {
      window.getdecorview (). setsystemuivisibility (view.system_ui_flag_visible);
    }
  }
  /**
   * Set status bar icon to dark and Meizu specific text style
   * Can be used to determine if it is a flyme user
   *
   * @param window The window to be set
   * @param dark whether to set the status bar font and icon color to dark
   * @return boolean returns true if successful
   * /
  public static boolean flymesetstatusbarlightmode (window window, boolean dark) {
    boolean result=false;
    if (window!=null) {
      try {
        windowmanager.layoutparams lp=window.getattributes ();
        field darkflag=windowmanager.layoutparams.class
            .getdeclaredfield ("meizu_flag_dark_status_bar_icon");
        field meizuflags=windowmanager.layoutparams.class
            .getdeclaredfield ("meizuflags");
        darkflag.setaccessible (true);
        meizuflags.setaccessible (true);
        int bit=darkflag.getint (null);
        int value=meizuflags.getint (lp);
        if (dark) {
          value |=bit;
        } else {
          value&= ~ bit;
        }
        meizuflags.setint (lp, value);
        window.setattributes (lp);
        result=true;
      } catch (exception e) {
      }
    }
    return result;
  }
  /**
   * Set the status bar font icon to dark,Requires miuiv6 or above
   *
   * @param window The window to be set
   * @param dark whether to set the status bar font and icon color to dark
   * @return boolean returns true if successful
   * /
  public static boolean miuisetstatusbarlightmode (window window, boolean dark) {
    boolean result=false;
    if (window!=null) {
      class clazz=window.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);
        if (dark) {
          extraflagfield.invoke (window, darkmodeflag, darkmodeflag);//The status bar is transparent and black font
        } else {
          extraflagfield.invoke (window, 0, darkmodeflag);//clear black font
        }
        result=true;
      } catch (exception e) {
      }
    }
    return result;
  }
}

Use in activity:

statusbarutil.setstatusbarlightmode (getwindow ());

effect:

Problems that arise:

1.statusbar background color has changed to colorprimarydark default color,But my configuration has a white background (for the specific configuration code, see the end).

Analyze the reasons:

setsystemuivisibility () refreshes the property configuration of the view.Since the statusbar uses the colorprimarydark property by default, the color will change back to the default color

At this point, the method of setting the background in step 1 will fail.

 private void initstatusbar () {
    if (statusbarview == null) {
      int identifier=getresources (). getidentifier ("statusbarbackground", "id", "android");
      statusbarview=getwindow (). findviewbyid (identifier);
    }
    if (statusbarview!=null) {
      statusbarview.setbackgroundresource (mvpconfig.statusdrawable);
    }
  }

Reason:When the incoming resid is the same, the background color will not be set again.

Solution:

 private void initstatusbar () {
    if (statusbarview == null) {
      int identifier=getresources (). getidentifier ("statusbarbackground", "id", "android");
      statusbarview=getwindow (). findviewbyid (identifier);
    }
    if (statusbarview!=null) {
      statusbarview.setbackgrounddrawable (null);//Set the background to null before setting;
      statusbarview.setbackgroundresource (mvpconfig.statusdrawable);
    }
  }

Modified effect:

Three. The complete code:

1.mvpconfig

public class mvpconfig {
  public static int statusdrawable;
  public static int toolbarbackgroundcolor;
  public static int toolbarbackgrounddrawable;
  public static int backdrawable;
  public static boolean isstatusbarlight;
  public static void setstatusbardrawable (@drawableres int statusdraw) {
    statusdrawable=statusdraw;
  }
  public static boolean isstatusbar () {
    return statusdrawable>0;
  }
  public static void settoolbardrawable (int toolbarbackgrounddrawable) {
    mvpconfig.toolbarbackgrounddrawable=toolbarbackgrounddrawable;
  }
  public static void setbackdrawable (int backdrawable) {
    mvpconfig.backdrawable=backdrawable;
  }
  public static void setisstatusbarlight (boolean isstatusbarlight) {
    if (build.version.sdk_int<build.version_codes.lollipop_mr1) {
      mvpconfig.statusdrawable=color.parsecolor ("#33ffffff");
    }
    mvpconfig.isstatusbarlight=isstatusbarlight;
  }

2.application

@override
  public void oncreate () {
    super.oncreate ();
    mvpconfig.settoolbardrawable (r.color.white);
    mvpconfig.setstatusbardrawable (r.color.white);
    mvpconfig.setbackdrawable (r.drawable.back);
    mvpconfig.setisstatusbarlight (true);
}

3.baseactivity

 @override
  protected void oncreate (bundle savedinstancestate) {
    super.oncreate (savedinstancestate);
 //Delay loading data.
    looper.myqueue (). addidlehandler (new messagequeue.idlehandler () {
      @override
      public boolean queueidle () {
        if (isstatusbarlight ()) {
          statusbarutil.setstatusbarlightmode (getwindow ());
        }
        if (isstatusbar ()) {
          initstatusbar ();
          getwindow (). getdecorview (). addonlayoutchangelistener (new view.onlayoutchangelistener () {
            @override
            public void onlayoutchange (view v, int left, int top, int right, int bottom, int oldleft, int oldtop, int oldright, int oldbottom) {
              initstatusbar ();
            }
          });
        }
        mpresenter.initdata ();
        return false;
      }
    });
  }
 private void initstatusbar () {
    if (statusbarview == null) {
      int identifier=getresources (). getidentifier ("statusbarbackground", "id", "android");
      statusbarview=getwindow (). findviewbyid (identifier);
    }
    if (statusbarview!=null) {
      if (isstatusbarlight ()) {
        statusbarview.setbackgrounddrawable (null);
      }
      statusbarview.setbackgroundresource (mvpconfig.statusdrawable);
    }
  }
  //Subclasses override this method,Controls whether the statusbar is changed
  protected boolean isstatusbar () {
    return mvpconfig.isstatusbar ();
  }
//Subclasses override this method,Controls whether the statusbar font color needs to be changed
  protected boolean isstatusbarlight () {
    return mvpconfig.isstatusbarlight;
  }

IV. Supplement:

Below 6.0, 5.0 native system cannot modify font color,I used a more tricky method,Set to translucent gray.

public static void setstatusbarlightmode (window window) {
    int type=getstatusbarlightmode (window);
    if (type == 1) {
      miuisetstatusbarlightmode (window, true);
    } else if (type == 2) {
      flymesetstatusbarlightmode (window, true);
    } else if (type == 3) {
      window.getdecorview (). setsystemuivisibility (view.system_ui_flag_light_status_bar);
    } else {
      //5.0
      if (build.version.sdk_int<build.version_codes.lollipop_mr1) {
        mvpconfig.statusdrawable=color.parsecolor ("#33ffffff");
      }
    }
  }

Because the background of the statusbarview in the window is directly modified, and frgament depends on the activity, when the activity and fragment jump directly,The status bar is not very applicable.For example:activity is blue, fragment needs to be white,The fragment needs to modify the status bar color through window.A bit troublesome.

  • Previous How to use the random function in C ++
  • Next Introduction to Hibernate core ideas and interfaces
  • Trends