Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >笔记54 | 管理系统UI(二)

笔记54 | 管理系统UI(二)

作者头像
项勇
发布于 2018-06-19 08:20:29
发布于 2018-06-19 08:20:29
1.3K00
代码可运行
举报
文章被收录于专栏:项勇项勇
运行总次数:0
代码可运行

全屏沉浸式应用

这节课将教您

  1. 选择一种沉浸方式
  2. 使用非粘性沉浸模式
  3. 使用粘性沉浸模式

Adnroid 4.4(API level 19)中引入为 setSystemUiVisibility()引入了一个新标签 SYSTEM_UI_FLAG_IMMERSIVE,它可以让应用进入真正的全屏模式。当这个标签与 SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN一起使用的时候,导航栏和状态栏就会隐藏,让你的应用可以接受屏幕上任何地方的触摸事件。

当沉浸式全屏模式启用的时候,你的Activity会继续接受各类的触摸事件。用户可以通过在边缘区域向内滑动来让系统栏重新显示。这个操作清空了 SYSTEM_UI_FLAG_HIDE_NAVIGATION(和 SYSTEM_UI_FLAG_FULLSCREEN,如果有的话)两个标签,因此系统栏重新变得可见。如果设置了的话,这个操作同时也触发了 View.OnSystemUiVisibilityChangeListener。然而, 如果你想让系统栏在一段时间后自动隐藏的话,你应该使用 SYSTEM_UI_FLAG_IMMERSIVE_STICKY标签。请注意,带有'sticky'的标签不会触发任何的监听器,因为在这个模式下展示的系统栏是处于暂时(transient)的状态。

图1展示了各种不同的“沉浸式”状态

图1. 沉浸模式状态.

在上图中:

  1. 非沉浸模式 —— 展示了应用进入沉浸模式之前的状态。也展示了设置 IMMERSIVE标签后用户滑动展示系统栏的状态。用户滑动后, SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN就会被清除,系统栏就会重新显示并保持可见。 请注意,最好的实践方式就是让所有的UI控件的变化与系统栏的显示隐藏保持同步,这样可以减少屏幕显示所处的状态,同时提供了更无缝平滑的用户体验。因此所有的UI控件跟随系统栏一同显示。一旦应用进入了沉浸模式,相应的UI控件也跟随着系统栏一同隐藏。为了确保UI的可见性与系统栏保持一致,我们需要一个监听器 View.OnSystemUiVisibilityChangeListener来监听系统栏的变化。这在下一节中将详细讲解。
  2. 提示气泡——第一次进入沉浸模式时,系统将会显示一个提示气泡,提示用户如何再让系统栏显示出来。 Note:如果为了测试你想强制显示提示气泡,你可以先将应用设为沉浸模式,然后按下电源键进入锁屏模式,并在5秒中之后打开屏幕。
  3. 沉浸模式—— 这张图展示了隐藏了系统栏和其他UI控件的状态。你可以设置 IMMERSIVEIMMERSIVE_STICKY来进入这个状态。
  4. 粘性标签——这就是你设置了 IMMERSIVE_STICKY标签时的UI状态,用户会向内滑动以展示系统栏。半透明的系统栏会临时的进行显示,一段时间后自动隐藏。滑动的操作并不会清空任何标签,也不会触发系统UI可见性的监听器,因为暂时显示的导航栏并不被认为是一种可见性状态的变化。

Noteimmersive类的标签只有在与 SYSTEM_UI_FLAG_HIDE_NAVIGATION, SYSTEM_UI_FLAG_FULLSCREEN中一个或两个一起使用的时候才会生效。你可以只使用其中的一个,但是一般情况下你需要同时隐藏状态栏和导航栏以达到沉浸的效果。

选择一种沉浸方式

SYSTEM_UI_FLAG_IMMERSIVESYSTEM_UI_FLAG_IMMERSIVE_STICKY都提供了沉浸式的体验,但是在上面的描述中,他们是不一样的,下面讲解一下什么时候该用哪一种标签。

  • 如果你在写一款图书浏览器、新闻杂志阅读器,请将 IMMERSIVE标签与 SYSTEM_UI_FLAG_FULLSCREEN, SYSTEM_UI_FLAG_HIDE_NAVIGATION一起使用。因为用户可能会经常访问Action Bar和一些UI控件,又不希望在翻页的时候有其他的东西进行干扰。 IMMERSIVE在该种情况下就是个很好的选择。
  • 如果你在打造一款真正的沉浸式应用,而且你希望屏幕边缘的区域也可以与用户进行交互,并且用户也不会经常访问系统UI。这个时候就要将 IMMERSIVE_STICKYSYSTEM_UI_FLAG_FULLSCREEN``SYSTEM_UI_FLAG_HIDE_NAVIGATION两个标签一起使用。比如做一款游戏或者绘图应用就很合适。
  • 如果你在打造一款视频播放器,并且需要少量的用户交互操作。你可能就需要之前版本的一些方法了(从Android 4.0开始)。对于这种应用,简单的使用 SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION就足够了,不需要使用 immersive标签。

使用非粘性沉浸模式

当你使用 SYSTEM_UI_FLAG_IMMERSIVE标签的时候,它是基于其他设置过的标签( SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN)来隐藏系统栏的。当用户向内滑动,系统栏重新显示并保持可见。

用其他的UI标签(如 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_STABLE)来防止系统栏隐藏时内容区域大小发生变化是一种很不错的方法。你也需要确保Action Bar和其他系统UI控件同时进行隐藏。下面这段代码展示了如何在不改变内容区域大小的情况下,隐藏与显示状态栏和导航栏。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// This snippet hides the system bars.
private void hideSystemUI() {
    // Set the IMMERSIVE flag.
    // Set the content to appear under the system bars so that the content
    // doesn't resize when the system bars hide and show.
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

你可能同时也希望在如下的几种情况下使用 IMMERSIVE标签来提供更好的用户体验:

  • 注册一个监听器来监听系统UI的变化。
  • 实现 onWindowFocusChanged()函数。如果窗口获取了焦点,你可能需要对系统栏进行隐藏。如果窗口失去了焦点,比如说弹出了一个对话框或菜单,你可能需要取消那些将要在 Handler.postDelayed()或其他地方的隐藏操作。
  • 实现一个 GestureDetector,它监听了 onSingleTapUp(MotionEvent)事件。可以使用户点击内容区域来切换系统栏的显示状态。单纯的点击监听可能不是最好的解决方案,因为当用户在屏幕上拖动手指的时候(假设点击的内容占据了整个屏幕),这个事件也会被触发。

更多关于此话题的讨论,可以观看这个视频

DevBytes: Android 4.4 Immersive Mode

使用粘性沉浸模式

当使用了 SYSTEM_UI_FLAG_IMMERSIVE_STICKY标签的时候,向内滑动的操作会让系统栏临时显示,并处于半透明的状态。此时没有标签会被清除,系统UI可见性监听器也不会被触发。如果用户没有进行操作,系统栏会在一段时间内自动隐藏。

图2展示了当使用 IMMERSIVE_STICKY标签时,半透明的系统栏展示与又隐藏的状态。

图2. 自动隐藏系统栏.

下面是一段实现代码。一旦窗口获取了焦点,只要简单的设置 IMMERSIVE_STICKY与上面讨论过的其他标签即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Override
public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}

Notes:如果你想实现 IMMERSIVE_STICKY的自动隐藏效果,同时也需要展示你自己的UI控件。你只需要使用 IMMERSIVEHandler.postDelayed()或其他类似的东西,让它几秒后重新进入沉浸模式即可。


响应UI可见性的变化

本节课将教你如果注册监听器来监听系统UI可见性的变化。这个方法在将系统栏与你自己的UI控件进行同步操作时很有用。

注册监听器

为了获取系统UI可见性变化的通知,我们需要对View注册 View.OnSystemUiVisibilityChangeListener监听器。通常上来说,这个View是用来控制导航的可见性的。

例如你可以添加如下代码在onCreate中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
        (new View.OnSystemUiVisibilityChangeListener() {
    @Override
    public void onSystemUiVisibilityChange(int visibility) {
        // Note that system bars will only be "visible" if none of the
        // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
            // TODO: The system bars are visible. Make any desired
            // adjustments to your UI, such as showing the action bar or
            // other navigational controls.
        } else {
            // TODO: The system bars are NOT visible. Make any desired
            // adjustments to your UI, such as hiding the action bar or
            // other navigational controls.
        }
    }
});

保持系统栏和UI同步是一种很好的实践方式,比如当状态栏显示或隐藏的时候进行ActionBar的显示和隐藏等等。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 项勇 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[Android] 关于系统工具栏和全屏沉浸模式
关于System Bars,之前写过几篇相关的文章:(链接等我把博客迁移好之后补上)
wOw
2018/09/18
1.6K0
[Android] 关于系统工具栏和全屏沉浸模式
笔记53 | 管理系统UI(一)
淡化状态栏和系统栏 如果要淡化状态和通知栏,在版本为4.0以上的Android系统上,你可以像如下使用 SYSTEM_UI_FLAG_LOW_PROFILE这个标签。 // This example uses decor view, but you can use any visible view. View decorView = getActivity().getWindow().getDecorView(); int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFIL
项勇
2018/06/19
1.6K0
Android状态栏微技巧,带你真正理解沉浸式模式
本文介绍了沉浸式模式在Android开发中的实现,主要包括了沉浸式模式的定义、实现方式、优缺点以及实例展示。
用户1158055
2018/01/08
2.4K0
Android状态栏微技巧,带你真正理解沉浸式模式
实现边到边的体验 | 让您的软键盘动起来 (一)
Android 11 中的新功能之一是可以让应用在对于屏幕上的软键盘打开和关闭的过程创建无缝过渡的动画效果,这一功能源自 Android 11 中对 WindowInsets API 的大量改进。
Android 开发者
2023/09/01
5980
实现边到边的体验 | 让您的软键盘动起来 (一)
浅谈Android自定义锁屏页的发车姿势
一、为什么需要自定义锁屏页 锁屏作为一种黑白屏时代就存在的手机功能,至今仍发挥着巨大作用,特别是触屏时代的到来,锁屏的功用被发挥到了极致。多少人曾经在无聊的时候每隔几分钟划开锁屏再关上,孜孜不倦,其酸爽程度不亚于捏气泡膜。确实,一款漂亮的锁屏能为手机增色不少,但锁屏存在的核心目的主要是三个:保护自己手机的隐私,防止误操作,在不关闭系统软件的情况下节省电量。 当下,各个款式的手机自带的系统锁屏完全能够满足这些需求,而且美观程度非凡,那么开发者为什么仍然需要构建自定义锁屏呢?让我们试想一个场景,一位正在使用音乐
腾讯Bugly
2018/03/23
2.6K0
浅谈Android自定义锁屏页的发车姿势
andriod使用超级播放器全屏时部分手机会出现白边或不能全屏
用户操作不会清除SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN。
腾讯云-qichengdeng
2019/09/17
2.7K0
andriod使用超级播放器全屏时部分手机会出现白边或不能全屏
浅谈 Android 自定义锁屏页的发车姿势
一、为什么需要自定义锁屏页   锁屏作为一种黑白屏时代就存在的手机功能,至今仍发挥着巨大作用,特别是触屏时代的到来,锁屏的功用被发挥到了极致。多少人曾经在无聊的时候每隔几分钟划开锁屏再关上,孜孜不倦,其酸爽程度不亚于捏气泡膜。确实,一款漂亮的锁屏能为手机增色不少,但锁屏存在的核心目的主要是三个:保护自己手机的隐私,防止误操作,在不关闭系统软件的情况下节省电量。   当下,各个款式的手机自带的系统锁屏完全能够满足这些需求,而且美观程度非凡,那么开发者为什么仍然需要构建自定义锁屏呢?让我们试想一个场景,一位正在
QQ音乐技术团队
2018/01/31
4.2K0
浅谈 Android 自定义锁屏页的发车姿势
关于 Android 中的各种 Bar 和“透明状态栏”的一些知识
其实这篇主要是讲解适配状态栏的,在这其中可能有些读者对状态栏(StatusBar)、ActionBar、ToolBar、TitleBar有点混淆或者感觉很混乱,所以就有了这其中的内容。
开发者
2019/12/26
3.3K0
关于 Android 中的各种 Bar 和“透明状态栏”的一些知识
Android 沉浸式解析和轮子使用
我们先一起来回顾一下实现沉浸式状态栏的一般套路。在 Android 上,关于对 StatusBar(状态栏)的操作,一直都在不断改善,并且表现越来越好,在 Android4.4 以下,我们可以对 StatusBar 和 NavigationBar 进行显示和隐藏操作。但是直到 Android4.4,我们才能真正意义上的实现沉浸式状态栏。从 Android4.4 到现在(Android 9),关于沉浸式大概可以分成三个阶段:
有赞coder
2020/08/25
3.5K0
Android 沉浸式解析和轮子使用
[Android学习整理]之监控并控制SystemUi(状态栏)的显示与隐藏
地址 CSDN 地址:http://blog.csdn.net/xiangyong_1521/article/details/51333437 工作中的一个需求,需要监控并动态控制到SystemUi(状态栏)的显示与隐藏,这是该需求的整理; 目录 onWindowAttributesChanged方法 OnSystemUiVisibilityChangeListene方法 setSystemUiVisibility(int visibility)控制 一、onWindowAttributesChanged方
项勇
2018/06/19
6.2K0
Android全面屏适配指南
全面屏是手机业界对于超高屏占比手机设计的一个宽泛的定义。从字面上解释就是,手机的正面全部都是屏幕,四个边框位置都是采用无边框设计,追求接近100%的屏占比。但受限于目前的技术,还不能做到手机正面屏占比100%的手机。现在业内所说的全面屏手机是指真实屏占比可以达到80%以上,拥有超窄边框设计的手机。
xiangzhihong
2022/11/30
2.3K0
Android的Dialog弹出时隐藏导航栏效果,目前认为的最优解
原本Android的ProgressDialog用法很简单,两三行代码就搞定了。但是,但是,但是,用在无人值守的自助终端上,总是把之前隐藏掉的导航栏和状态栏显示出来。这是不可接受的。总不能让设备给用户随意摆弄吧,进入系统把你应用给搞没了都有可能。
杨永贞
2020/08/04
5.2K0
全屏、沉浸式、fitSystemWindow使用及原理分析:全方位控制“沉浸式”的实现
状态栏与导航栏属于SystemUi的管理范畴,虽然界面的UI会受到SystemUi的影响,但是,APP并没有直接绘制SystemUI的权限与必要。APP端之所以能够更改状态栏的颜色、导航栏的颜色,其实还是操作自己的View更改UI。可以这么理解:状态栏与导航栏拥有自己独立的窗口,而且这两个窗口的优先级较高,会悬浮在所有窗口之上,可以把系统自身的状态栏与导航栏看做全透明的,之所有会有背景颜色,是因为下层显示界面在被覆盖的区域添加了颜色,之后,通过SurfaceFlinger的图层混合,好像是状态栏、导航栏自身有了背景色。看一下一个普通的Activity展示的时候,所对应的Surface(或者说Window也可以)。
看书的小蜗牛
2018/06/29
6.2K0
全屏、沉浸式、fitSystemWindow使用及原理分析:全方位控制“沉浸式”的实现
Android 沉浸式全屏
Android 4.4 带来了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏、 虚拟按键动态隐藏, 应用可 以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 “身临其境” 的体验。
beginor
2020/08/10
1.7K0
Android 沉浸式全屏
Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果
需求:    手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态栏会再次隐藏。 实现代码: @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.a
听着music睡
2018/05/18
8510
android沉浸式状态栏的实现
在style.xml中添加 <style name="Theme.Timetodo" parent="@android:style/Theme.Holo.Light"> <!-- translucent system bars --> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </s
xiangzhihong
2018/01/30
1.3K0
相关推荐
[Android] 关于系统工具栏和全屏沉浸模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验