【移动应用开发技术】透明系统栏及沉浸模式的总结_第1页
【移动应用开发技术】透明系统栏及沉浸模式的总结_第2页
【移动应用开发技术】透明系统栏及沉浸模式的总结_第3页
【移动应用开发技术】透明系统栏及沉浸模式的总结_第4页
【移动应用开发技术】透明系统栏及沉浸模式的总结_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】透明系统栏及沉浸模式的总结

关于所谓的“沉浸式”,我有许多话要说,因为这个东西实在是折磨了我许多的时间。实现的方式有许多,兼容性问题也不少。官方文档也让我感到也有些云里雾里。那些“长得很相似”的Flag,适用情况很接近的设置方法,让我不得不一个个测试,然而却一次次推翻。模拟器上测试;真机上测试;4.4版本上的测试;5.0后版本的测试;有导航栏手机上的测试;老掉牙手机上的测试。总而言之,这个东西的探索让我深刻地体会到android系统兼容性问题的麻烦。当你功能开发占据10%,而处理兼容性问题占据90%的时候。你不得不思考这样一个问题:“兼容性真的有那么重要吗?”撇开这个问题,以投入和产出的角度显然是不太划得来的,但是收获的角度:我学习了解了View的加载机制、DecorView在不同版本上的实现以及发展、养成了遇到问题第一时间查阅官方文档的习惯。

关键词1、系统栏Systembar(包括状态栏Statusbar,导航栏Navigationbar)2、内容主体暂且可以理解为Window中除了Systembar以外的窗口

实现原理:1、将SystemBar透明化2、根据不同情况决定内容主体是否需要延伸到SystemBar下方

一、将SystemBar透明化主题中设置属性:<itemname="android:windowTranslucentStatus">true</item><itemname="android:windowTranslucentNavigation">true</item>代码中设置Flag:getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明状态栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//透明导航栏5.0后设置:

getWindow().setStatusBarColor(Color.TRANSPARENT);

getWindow().setNavigationBarColor(Color.TRANSPARENT);

二、根据不同情况决定内容主体是否需要延伸到SystemBar下主题中设置属性:

<itemname="android:windowFullscreen">true</item>代码中设置Flag:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);FLAG_TRANSLUCENT_STATUS单独使状态栏透明化FLAG_TRANSLUCENT_NAVIGATION单独使导航栏透明化4.1后更多选项的设置:ViewdecorView=getWindow().getDecorView();decorView.setSystemUiVisibility(Flag);Flag的值需要了解以下几种情况:1、SYSTEM_UI_FLAG_FULLSCREEN2、SYSTEM_UI_FLAG_HIDE_NAVIGATION3、SYSTEM_UI_FLAG_IMMERSIVE4、SYSTEM_UI_FLAG_IMMERSIVE_STICKY5、SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN6、SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION7、SYSTEM_UI_FLAG_LAYOUT_STABLE8、SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

SYSTEM_UI_FLAG_FULLSCREEN隐藏状态栏,主体向上偏移,但在手动下拉会重新显示状态栏并清除该flag。View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE限制主体位置保持不变,状态栏留白

SYSTEM_UI_FLAG_HIDE_NAVIGATION隐藏导航栏,主体向下偏移,由于导航栏太重要了,所以只要和Activity进行任何交互都会重新显示导航栏,并清除该flag和SYSTEM_UI_FLAG_FULLSCREEN。View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_LAYOUT_STABLE限制主体位置保持不变,导航栏留白

SYSTEM_UI_FLAG_LAYOUT_STABLE保持内容主体位置不变,不随着Systembar的隐藏显示而偏移

SYSTEM_UI_FLAG_IMMERSIVE沉浸模式:只能和SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用。简单交互不会重新显示导航栏

SYSTEM_UI_FLAG_IMMERSIVE_STICKY沉浸模式:只能和SYSTEM_UI_FLAG_FULLSCREEN或SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用。下拉状态栏位置可以短暂显示状态栏和导航栏,然后再次隐藏。

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN主体占据全部屏幕,但不隐藏状态栏,这里的layout可以理解为内容主体

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION主体占据全部屏幕,但不隐藏导航栏,这里的layout可以理解为内容主体

SYSTEM_UI_FLAG_LAYOUT_STABLE这个Flag确实有点难以理解,唯一读懂的是在各种flag切换的时候能保持内容主体的稳定性。如果你不想flag变换的时候内容主体上下偏移,就需要设置SYSTEM_UI_FLAG_LAYOUT_STABLE。

View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR浅色状态栏模式:对应于图标变深色,防止浅色背景导致状态栏看不清,不设置是深色模式

实践验证过程:ViewdecorView=getWindow().getDecorView();decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);状态栏不会隐藏,仍占据着位置,但内容可以侵入状态栏下方

decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);View.SYSTEM_UI_FLAG_FULLSCREEN状态栏下滑,主体布局就会下降一个状态栏的高度,很突兀View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN状态栏下滑,主体布局位置不变化

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE;这个和单独使用View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN区别在哪儿,还没发现

andriod系统提供了一些透明状态栏/导航栏的主题以供使用:<stylename="Theme.Material.Light.NoActionBar.TranslucentDecor">

<itemname="windowTranslucentStatus">true</item>

<itemname="windowTranslucentNavigation">true</item>

<itemname="windowContentOverlay">@null</item></style>

SYSTEM_UI_FLAG_HIDE_NAVIGATION|SYSTEM_UI_FLAG_IMMERSIVESYSTEM_UI_FLAG_IMMERSIVE必须与SYSTEM_UI_FLAG_HIDE_NAVIGATION结合使用才有意义加上SYSTEM_UI_FLAG_IMMERSIVE,则导航栏在隐藏后不会因与界面的交互而呼出。类似于看视频时进入全屏模式。

SYSTEM_UI_FLAG_FULLSCREEN|SYSTEM_UI_FLAG_HIDE_NAVIGATION进入全屏模式,但用户与界面进行最简单的交互都会重新显示状态栏,导航栏

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_IMMERSIVE进入全屏模式,用户交互会重新显示状态栏,导航栏,不会再隐藏

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_FULLSCREEN|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY进入全屏模式,用户交互会短暂显示状态栏,导航栏,然后再隐藏

总结:比较简洁的透明状态栏的做法是:方法一:适合4.1及以上if(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){

Viewwindow=getWindow().getDecorView();

window.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

|View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

getWindow().setStatusBarColor(Color.TRANSPARENT);}对于不需要延伸至状态栏下方的组件,使用android:fitsSystemWindows="true"将进行设置即可。本质上是添加一个状态栏高度的paddingTop属性,所以android:layout_height属性不要使用"250dp"这种固定数值,可以使用"wrap_content"结合android:minHeight="250dp"的方式。

方法二:适合4.1及以上同方法一:<itemname="android:windowTranslucentStatus">true</item>

<itemname="android:windowTranslucentNavigation">true</item>结合android:fitsSystemWindows属性

方法三:适合4.0及以下的版本<itemname="android:windowFullscreen">true</item>

<itemname="android:windowContentOverlay">@null</item>或者代码中:getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);方法三使用android:fitsSystemWindows是无效的。所以我的做法是给需要向下偏移的组件设置一个paddingTop的值,并在v21,v19等不同版本设置不同的值做兼容(源码可知statusbar高度是25dp)。这里默认所有手机平台都是25dp。网上的做法是选择性填充一个View,该View的Height是动态获取的statusbar的高度。这个做法兼容了不同厂商自己定制的UI使用不同于Google官方25dp的状态栏高度的情况。如红米note2是20dp,魅族note5是22dp。

另外对于setFlags方法,同样有单独设置状态栏和导航栏的方法:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

对于这两个属性而言,android:fitsSystemWindows有效,但在设置了FLAG_TRANSLUCENT_NAVIGATION的时候,内容主体也会向下偏移一个导航栏的高度,可见这里的android:fitsSystemWindows指的是SystemBar,而不仅仅是StatusBar。方法四:适合于5.0以后结合DesignSupport库中的CoordinatorLayout+AppBarLayout+CollapsingToo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论