视频播放器使用appcompat-v7在Android中点亮模式

时间:2014-11-10 18:45:51

标签: android media-player android-support-library android-appcompat android-toolbar

我正在将代码库从原生Holo(Theme.Holo等)移植到appcompat-v7Theme.AppCompat等等)。如果您不想阅读详细信息,最后一部分包含 tl; dr


问题

一切正常但我有问题复制一个很容易使用旧ActionBar的行为。我有一个视频播放器,在风景中我希望它的行为像YouTube:隐藏(动画)播放器控件,应用栏和状态栏。在用户交互时,UI控件应该保持“熄灯”模式并返回正常状态。如果用户没有触摸屏幕X秒,则计时器将返回到熄灯模式。使用ActionBar的相同代码不会使用Toolbar

所以,我使用的是:

  • 不透明状态栏
  • setSystemUiVisibility()使用以下其中一个组合:
    • 默认:View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    • 熄灯:View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
  • minSdkVersion是16
  • 显示和隐藏ActionBar我只是简单地调用了show()hide()
  • 在子类Toolbar的应用栏上实现相同的行为,并添加了show()hide()方法来执行相同操作(首先只使用setVisibility(),并且然后使用动画 - 获得相同的结果)

LAYOUT_STABLE使得appbar最终会落在状态栏后面(因为它意味着fitSystemWindows。因为appbar是视图层次结构中的普通View而不是像ActionBar一样的装饰,它受到那面旗帜的影响。这就是我在屏幕上看到的:

App bar behind the status bar

不能立即清楚工具栏边界是什么,因为应用栏在黑暗中是黑暗的,但您可以看到标题被剪切并且“未对齐”。这是因为工具栏的大小正确但位于状态栏后面。我的主要问题是,当时没有公共API可以获取状态栏的高度,矩形或其他任何内容来垂直移动我的应用栏以显示状态栏下方。

测试主要是在LPX13D上的N5上进行的(在撰写本文时最新的Lollipop公共版本),但在Android 4.4上也可以看到相同的情况。


hacky解决方案

那就是说,经过相当长的一段时间和一些失败的尝试使它以一种不太苛刻的方式工作(包括我自己试图把它装入装饰的相当绝望的尝试),我采取了这种令人讨厌的方式使它工作:

  1. onResume中:
    一个。即使我通常不这样做(风景),也请致电setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE) 湾注册OnPreDrawListener

  2. OnPreDrawListener
    一个。使用View root = getRootView().findViewById(R.id.my_root)获取根视图 湾获取根视图高度:int rootTop = getAbsoluteViewTop(root)(见下文)
    C。使用顶部(将其作为状态栏高度)作为appbar的paddingTop d。设置我通常使用的SystemUiVisibility(LAYOUT_STABLE等)
    即取消绘图传递

  3. 在下一个绘图过程中,取消注册OnPreDrawListener
  4. 这是getAbsoluteViewTop()方法:

    private int getAbsoluteViewTop(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        return location[LOCATION_Y];
    }
    

    tl; dr和问题

    tl; dr :除非使用hacky hacks,否则无法使用Toolbar进行正确的“熄灯”模式。

    问题:使用Toolbar实施此熄灯模式是否有正式且干净的方式?
    我在文档中找不到任何内容。状态栏无法访问(并且在SO上找到它的大小的所有方法都被破坏了,仅供参考)。但也许我错过了一些东西。我很乐意摆脱这种黑客攻击。

2 个答案:

答案 0 :(得分:1)

当您希望视图层次结构中的某些元素为全屏,并且某些元素位于状态栏或操作栏下方时,我发现fitssystemwindows非常不可靠。但我从未见过状态栏后面的操作栏。工具栏是否设置为活动操作栏?你在使用Window.FEATURE_ACTION_BAR_OVERLAY吗?无论如何,如果您只需要为paddingTop中的onResume()获取一些像素,那么执行类似下面的操作(而不是使用{{1 }}第

OnPreDrawListener

答案 1 :(得分:1)

不确定这是否会有所帮助,但是您已经看过了

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

在您的视频活动的onCreate方法中?这可能是一个很好的起点。这基本上隐藏了状态栏并使我的视频全屏显示。

这也是我也使用的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:background="@color/black">

        <VideoView
            android:id="@id/videoSurface"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_centerInParent="true"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_gravity="center"
            />

</RelativeLayout>

我知道有些参数是多余的,但最终它给了我想要的效果。这可能是一个很好的起点吗?