video播放器使用appcompat-v7在Android中熄灭模式

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


问题

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

所以,我使用的是:

  • 一个不透明的状态栏
  • setSystemUiVisibility()使用这些组合之一:
    • 默认: View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 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 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()
  • 在应用程序栏上实现相同的行为我subclassed Toolbar并添加一个show()和一个hide()方法相同(首先简单地使用setVisibility() ,然后使用animation – 获得相同的结果)

LAYOUT_STABLE使得appbar最终会在状态栏后面(因为它意味着一个fitSystemWindows 。由于appbar是视图层次结构中的普通视图,并不像ActionBar那样装饰,它受到那个标志这是我在屏幕上看到的:

状态栏后面的应用栏

不立即清除工具栏边界是什么,因为应用程序栏在黑暗中是黑暗的,但是您可以看到标题被剪切和“未alignment”。 这是因为工具栏大小正确,但在状态栏后面。 我的主要问题是在这一点上,没有公共的API来获得状态栏高度,矩形或其他任何东西来垂直移动我的应用程序栏以显示在状态栏下方。

testing主要是在LP513D上的N5上进行的(在编写本文时为最新的Lollipop公开构build版本),但Android 4.4上也可以看到相同的结果。


哈克解决scheme

也就是说,经过相当一段时间和一些失败的尝试,使得它以不太疯狂的方式工作(包括试图把它装进装饰的相当绝望的尝试),我采取了这种使它工作的恶劣方式:

  1. onResume
    一个。 调用setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE)即使我通常不这样做(横向)
    湾 注册一个OnPreDrawListener

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

  3. 在下一个绘图阶段,取消注册OnPreDrawListener

这是getAbsoluteViewTop()方法:

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

tl;博士和问题

博士 :没有办法做一个正确的“熄灯”模式与Toolbar除非hacky黑客被雇用。

问:是否有一个官方的,干净的方式来实现这个熄灯模式与Toolbar
我找不到文档中的任何内容。 状态栏不可访问(所有的方法来find它的大小,你可以find这是打破,FYI)。 但也许我错过了一些东西。 我很想摆脱这个黑客。

我发现fitssystemwindows相当不可靠,当你想要视图层次结构的一些元素是全屏和一些元素在状态栏或操作栏下面。 但是我从来没有见过状态栏后面的动作栏。 工具栏是否设置为活动操作栏? 你在使用Window.FEATURE_ACTION_BAR_OVERLAY吗? 无论如何,如果你所需要的只是在onResume()获得paddingTop的像素数量,它可能会稍微干净一点(尽pipe如此),而不是使用OnPreDrawListener

 class MyVideoActivity extends Activity { Toolbar bar; //... @Override protected void onResume() { super.onResume(); bar.setPaddingTop(getStatusBarHeight()); } int getStatusBarHeight() { int result = 0; Resources res = getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = res.getDimensionPixelSize(resourceId); } return result; } } 

不知道这是否会帮助,但你有没有看过使用

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

在你的video活动的onCreate方法? 这可能是一个很好的起点。 这基本上隐藏状态栏,使我的video全屏。

这是我也使用的布局:

 <?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> 

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