Android:调整MediaController以适应系统用户界面不适用于操作栏

时间:2015-08-08 10:02:42

标签: android android-layout android-actionbar android-videoview mediacontroller

我有一个Activity,它使用带有自定义MediaController的VideoView显示视频。系统UI处于隐藏状态,直到用户点按屏幕以显示MediaController(就像在YouTube或照片应用中一样)。

以下方法负责隐藏系统UI:

private void hideSystemUi() {
    int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
                View.SYSTEM_UI_FLAG_FULLSCREEN |
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        getWindow().getDecorView().setSystemUiVisibility(flags);

}

活动的布局:

<FrameLayout android:id="@+id/root"
             xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:focusable="true"
             android:keepScreenOn="true">

    <com.google.android.exoplayer.AspectRatioFrameLayout
        android:id="@+id/video_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center">

        <SurfaceView
            android:id="@+id/surface_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"/>

    </com.google.android.exoplayer.AspectRatioFrameLayout>
</FrameLayout>

然后我通过以下代码将MediaController添加到video_frame

mMediaController.setAnchorView(findViewById(R.id.video_frame));

使用Nexus 5进行测试时,我注意到在显示MediaController时,软导航栏与MediaController UI重叠。我设法通过将以下属性添加到MediaController布局的根目录来修复它:

android:fitsSystemWindows="true"

到目前为止一切顺利。只要我的活动主题为Theme.AppCompat.NoActionBar,这就完美无缺。现在我正在重构应用程序,根据Material的材质设计指南获取它,我必须显示ActionBar。 所以我把主题更改为Theme.AppCompat并猜测是什么?系统UI再次与MediaController重叠。似乎android:fitsSystemWindows="true"完全没有影响。

我试图将android:fitsSystemWindows="true"直接设置为Activity主题本身,它似乎解决了重叠的问题,但后来又遇到了另一个问题,即VideoView以一种非常奇怪的方式从随机方向填充,而不是像过去那样按比例缩放以适应屏幕。

我花了好几个小时,仍然无法找到一个干净的解决方案。 请注意我需要一个适用于平板电脑和手机的解决方案。 正如您可能知道的那样,在平板电脑上,在横向模式下,软导航栏会出现在屏幕底部。 如果可能,我更愿意通过XML解决问题。

1 个答案:

答案 0 :(得分:2)

在检查了Android Studio的全屏活动模板后,我注意到在FullscreenActivity布局中,他们使用android:fitsSystemWindows="true"的方式与我的方式略有不同。

这是模板附带的布局(activity_fullscreen.xml):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="#0099cc"
             tools:context=".FullscreenActivity">

    <!-- The primary full-screen view. This can be replaced with whatever view
         is needed to present your content, e.g. VideoView, SurfaceView,
         TextureView, etc. -->
    <TextView android:id="@+id/fullscreen_content"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:keepScreenOn="true"
              android:textColor="#33b5e5"
              android:textStyle="bold"
              android:textSize="50sp"
              android:gravity="center"
              android:text="@string/dummy_content"/>

    <!-- This FrameLayout insets its children based on system windows using
         android:fitsSystemWindows. -->
    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:fitsSystemWindows="true">

        <LinearLayout android:id="@+id/fullscreen_content_controls"
                      style="?metaButtonBarStyle"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_gravity="bottom|center_horizontal"
                      android:background="@color/black_overlay"
                      android:orientation="horizontal"
                      tools:ignore="UselessParent">

            <Button android:id="@+id/dummy_button"
                    style="?metaButtonBarButtonStyle"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="@string/dummy_button"/>

        </LinearLayout>
    </FrameLayout>

</FrameLayout>

我注意到他们有一个额外的FrameLayout容器集android:fitsSystemWindows="true",它包含了屏幕底部的实际布局容器(在我的例子中,这是MediaController)。 / p>

我添加FrameLayout以包装我的MediaController布局,如上面的代码段所示,我的问题就消失了!真的很奇怪,我需要有额外的布局容器来解决这个问题。特别是当Android Studio现在说我有&#34;无用的父母&#34;。

总而言之,这是我的Activity布局的完整解决方案:

<FrameLayout android:id="@+id/root"
             xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:focusable="true"
             android:keepScreenOn="true">

    <com.google.android.exoplayer.AspectRatioFrameLayout
        android:id="@+id/video_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center">

        <SurfaceView
            android:id="@+id/surface_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"/>

    </com.google.android.exoplayer.AspectRatioFrameLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <LinearLayout         android:id="@+id/controller_frame"
                              android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_gravity="bottom|center_horizontal"
                      android:orientation="horizontal">

        </LinearLayout>

    </FrameLayout>
</FrameLayout>

我将MediaControllercontroller_frame挂钩,而不是像以前那样将video_frame连接起来:

mMediaController.setAnchorView(findViewById(R.id.controller_frame));