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 来配合控制

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

react-native android状态栏的实现的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. 使用UINavigationController进行iOS 7自定义当前转换

    解决方法我有同样的问题,并解决了在设置此框架之前将toViewController添加到容器.反转如下的行:

  6. iOS – UINavigationController,隐藏navigationBar

    快速以及obj-c的答案非常受欢迎编辑:我试过以下各种版本,问题依然存在–.-编辑2:打印:在viewDidLoad返回20之后解决方法更新:只需在ViewDidLoad方法中添加它即可

  7. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  8. ios – TabBarController上的彩色状态栏,导航栏无法正常工作

    我在这里阅读了很多帖子,并尝试了大多数提到的选项,但没有人为我解决问题.我有一个基于标签栏控制器的应用程序.每个选项卡都是一个UIViewController,顶部有一个导航栏.将此代码添加到AppDelegate为我提供了带有白色文本的橙色导航栏,但是带有黑色文本的白色状态栏.阅读各种页面上的答案建议将以下内容添加到View控制器:然后在ViewDidLoad中调用它:这让我得到一个带有白色文本的白色状态栏,我现在如何让状态栏变为橙色以匹配我的导航栏?

  9. ios – 状态栏大小错误,包含UINavigationController

    这是你永远不应该做的事情.只需将这些行添加到您的代码中:现在导航控制器的视图有一个框架,并相对于其超视图维护它.

  10. ios – 导航工具栏从全屏视频返回后垂直延伸

    第一个屏幕截图是在全屏播放视频之前拍摄的.第二个是在视频全屏打开并关闭后拍摄的.知道为什么导航工具栏有扩展吗?注意:汉堡包按钮不是导航项目的一部分.它在父级的覆盖中伪造,将其子控制器保存在标准容器中.源内没有什么特别之处:更新:这似乎仅在最新版本的iOS9.3上存在问题解决方法从截图中看,状态栏的高度看起来会加倍.试试这个:-在播放视频之前,请隐藏状态栏结束视频后,显示状态栏

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部