当前位置: 移动技术网 > IT编程>开发语言>JavaScript > react-native android状态栏的实现

react-native android状态栏的实现

2018年08月12日  | 移动技术网IT编程  | 我要评论

react-native 开发app的时候难免会遇到状态栏的,背景颜色和字体颜色与app内容页面,色调适配,间言之就是将状态栏颜色与app颜色一致,使用户界面更加整体。

1.android设备系统元素

  1. 导航栏:就是设备顶部的网络、时间、电量等信息栏
  2. actionbar: 返回按钮以及系统默认的header区域,rn开发中一般不会用到,rn中在navigation中进行定制
  3. 导航栏: 设备下方的物理返回、回桌面、选择应用程序等系统导航栏

2.状态栏的呈现形式

  1. 默认展示,一直显示手机系统的状态栏
  2. 透明状态栏,状态栏背景颜色透明,状态栏颜色与app颜色一致,用户界面更加整体。
  3. 隐藏状态栏(沉浸式),状态栏完全隐藏,类似于全屏游戏、视频播放器的效果

2.1 默认展示

系统默认状态栏样式,无法改变

2.2 透明状态栏

透明状态栏很常见,大多数的app都是使用这种模式,使得状态栏颜色与app颜色一致,使用户界面更加整体,整个应用看起来更加美观。

实现透明的状态栏的方式很多:

一、使用app的主题进行配置,在app/main/res/values/styles.xml中设置主题

<resources>

 <!-- base application theme. -->
 <style name="apptheme" parent="theme.appcompat.light.noactionbar">
  <item name="android:windowtranslucentstatus">true</item> // 设置状态栏不占据空间
  // <item name="android:windowlightstatusbar">true</item> // 设置状态栏字体颜色
 </style>

</resources>

这种方式支持api19, 即android4.4及以上,会在app启动的时候就生效, 在app启动时有权限确认、系统弹窗等也不受影响,在弹出modal之类的深色蒙层时状态栏字体会变成成浅色

只设置 <item name="android:windowtranslucentstatus">true</item> 这种方式设置的透明状态栏,状态栏字体默认白色,无法再动态通过statusbar改变状态栏的背景颜色,在做需要改变状态栏背景颜色的时候就比较尴尬了

再加一个 <item name="android:windowlightstatusbar">true</item> 这样设置状态栏字体颜色之后,在深色modal弹出的时候字体不会动态改变成白色,但可以通过statusbar设置barstyle来改变,实际上也不是很方便

二、android原生设置,在mainactivity的oncreate中进行设置

protected void oncreate(bundle savedinstancestate) {
 super.oncreate(savedinstancestate);
 // 设置透明状态栏
 if (build.version.sdk_int >= 21) {
  view decorview = getwindow().getdecorview();
  int option = view.system_ui_flag_layout_fullscreen
    | view.system_ui_flag_layout_stable;
  decorview.setsystemuivisibility(option);
  getwindow().setstatusbarcolor(color.transparent);
 }
 
 // 设置透明状态栏和透明导航栏
 if (build.version.sdk_int >= 21) {
  view decorview = getwindow().getdecorview();
  int option = view.system_ui_flag_layout_hide_navigation
    | view.system_ui_flag_layout_fullscreen
    | view.system_ui_flag_layout_stable;
  decorview.setsystemuivisibility(option);
  getwindow().setnavigationbarcolor(color.transparent);
  getwindow().setstatusbarcolor(color.transparent);
 }
}

透明式状态栏,只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。 接下来我们使用了 system_ui_flag_layout_fullscreen system_ui_flag_layout_stable ,注意两个flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,也就是说状态栏不再占据空间。最后再调用window的setstatusbarcolor()方法将状态栏设置成透明色就可以了。

三、使用rn的statusbar来设置,在app首次加载的页面中对状态栏进行设置

<statusbar backgroundcolor='transparent' translucent barstyle={'dark-content'} />

这种方式,会在app刚启动的时候和app启动时有权限确认、系统弹窗等会先试用系统的默认状态栏,加载app页面之后再改变成上面设置的样式。 好处在于可以动态进行设置状态栏的样式。

statusbar属性简介:

  1. animated: bool 指定状态栏的变化是否应以动画形式呈现。目前支持这几种样式:backgroundcolor, barstyle和hidden
  2. hidden: bool 是否隐藏状态栏。
  3. backgroundcolor: 状态栏的背景色。
  4. translucent: bool 指定状态栏是否透明。设置为true时,应用会在状态栏之下绘制(即所谓“沉浸式”——被状态栏遮住一部分)。常和带有半透明背景色的状态栏搭配使用。
  5. barstyle: enum('default', 'light-content', 'dark-content') 设置状态栏文本的颜色。

以上几种方式都会有一个问题,状态栏不再占据空间,因此在页面布局的时候需要加 paddingtop 值为状态栏的高度。

纯前端就可以实现,这也是适配目前主流刘海屏的一种方式,利用statusbar.currentheight可以获取到设备状态栏的高度。

2.3 隐藏 状态栏 和 导航栏

super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
view decorview = getwindow().getdecorview();
int option = view.system_ui_flag_hide_navigation | view.system_ui_flag_fullscreen;
decorview.setsystemuivisibility(option);
actionbar actionbar = getsupportactionbar();
actionbar.hide();

3. 浅色状态栏的兼容性配置

目前市面上的浅色状态栏基本都是 白底黑字, 支持这种设置的有android6.0及其以上; miui v6及以上, flyme 4.0及以上

具体兼容方案如下:

flyme 4.0及以上

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;
}

android6.0及以上

public static void setandroidnativelightstatusbar(activity activity, boolean dark) {
 //状态栏字体图标颜色
 view decor = activity.getwindow().getdecorview();
 if (dark) {
  if (build.version.sdk_int >= build.version_codes.m) {
   decor.setsystemuivisibility(view.system_ui_flag_light_status_bar //浅色状态栏(字体图标白色)
     | view.system_ui_flag_layout_fullscreen //contentview 全屏(置于statusbar之下)
     | view.system_ui_flag_layout_stable);
  }
 } else {
  decor.setsystemuivisibility(view.system_ui_flag_visible);
 }
}

miui v6及以上

public static boolean miuisetstatusbarlightmode(activity activity, boolean dark) {
 if(build.version.sdk_int >= 24){
  return false;
 }
 boolean result = false;
 window window=activity.getwindow();
 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);//状态栏透明且黑色字体
   }else{
    extraflagfield.invoke(window, 0, darkmodeflag);//清除黑色字体
   }
   result=true;

   if (build.version.sdk_int >= build.version_codes.m) {
    //开发版 7.7.13 及以后版本采用了系统api,旧方法无效但不会报错,所以两个方式都要加上
    if(dark){
     activity.getwindow().getdecorview().setsystemuivisibility( view.system_ui_flag_layout_fullscreen| view.system_ui_flag_light_status_bar);
    }else {
     activity.getwindow().getdecorview().setsystemuivisibility(view.system_ui_flag_visible);
    }
   }
  }catch (exception e){

  }
 }
 return result;
}

在mainactivity的oncreate中调用

lightstatusbarutil.flymesetstatusbarlightmode(this.getwindow(), false);
lightstatusbarutil.miuisetstatusbarlightmode(this, false); 
lightstatusbarutil.setandroidnativelightstatusbar(this, true);

总结

实现透明状态栏,以上方案都没有完全兼容android 4.4以下版本,个人觉得比较合适的做法是 android设置透明状态栏 + 浅色状态栏的兼容性配置 + statusbar 来配合控制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网