在旋转时更改 MediaController 位置

Change MediaController position on rotation

我正在尝试根据方向变化动态更改 MediaController 的锚点。经过我所有的尝试,这并没有按需要工作。

也许你可以指出我的错误。

简而言之:

人像模式:

  1. weightSum = 1.
  2. SurfaceView体重:0.4
  3. MediaControllerHorizontalScrollView 权重:0.6
  4. MediaController 始终可见且不隐藏

横向模式:

  1. SurfaceView权重:0.0(全屏)

  2. MediaControlls = View.Gone(我需要将其锚点更改为 SurfaceView。并弹出 onTouch。但是如何??)


代码代码:

player.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true"
    tools:context="tenkol.design.com.imbrecords.ActivityExoPlayer"
    android:weightSum="1"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/surface_wrapper"
        android:layout_weight="0.4">

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

        <View
            android:id="@+id/shutter"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/black" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0.6"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/controls_wrapper"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dp">
        </FrameLayout>

        <HorizontalScrollView
            android:id="@+id/myGallery"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp">

            <LinearLayout
                android:id="@+id/channelsScrollView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="horizontal"
                android:paddingBottom="5dp"
                android:paddingTop="5dp"
                />
        </HorizontalScrollView>

    </LinearLayout>

</LinearLayout>

转换代码:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (Global.getScreenOrientation(this) == Configuration.ORIENTATION_LANDSCAPE) {
        //hide action bar
        getSupportActionBar().hide();
        if (myGallery != null) {
            //hide HorizontalScrollView
            myGallery.setVisibility(View.GONE);
        }
        //make surface fullscreen
        surfaceWrapper.setLayoutParams(new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, 0f));
        controlsWrapper.setLayoutParams(new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, 0f));
        //hide mediaController
        mc.hide();
        controlsWrapper.setVisibility(View.GONE);
    }
    if (Global.getScreenOrientation(this) == Configuration.ORIENTATION_PORTRAIT) {
        //and here restore everything
        getSupportActionBar().show();
        if (myGallery != null) {
            myGallery.setVisibility(View.VISIBLE);
        }

        surfaceWrapper.setLayoutParams(new LinearLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT, 0.4f));
        controlsWrapper.setLayoutParams(new LinearLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, 0.6f));
        controlsWrapper.setVisibility(View.VISIBLE);
    }
}

我试过的:

1) 当 Landscape 时:创建另一个 mediaController 并绑定到根视图(不起作用):

  mediaController.setAnchorView(root);
  mediaController.setMediaPlayer(player.getPlayerControl());
  mediaController.setEnabled(true);
  mediaController.show(3);

2) Landscape 时:更改之前的锚点 MediaController (Nah).

  mc.setAnchorView(surfaceWrapper);
  mc.show(3);

3)接口surfaceChanged(还是没有):

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    if (Global.getScreenOrientation(this) == Configuration.ORIENTATION_LANDSCAPE) {
        mc.setAnchorView(surfaceWrapper);
        mc.setMediaPlayer(player.getPlayerControl());
        mc.setVisibility(View.VISIBLE);
        mc.show(3);
    }
}

那么如何在 LANDSCAPE 模式下将 MediaController 的锚点动态更改为 SurfaceView

P.S. 告知是否需要更多代码。

由于您覆盖了 onConfigurationChanged,我认为这意味着 activity 不允许 Android 管理其方向更改,而是选择自行完成所有操作。这通常不是一个好主意,您目前正面临着做出该决定的痛苦。 :-(

如果我可以提出建议:让 Android 管理您的 activity 的生命周期,并使用不同的布局(例如 layout-land/views.xml 和 layout-port/views.xml).这将允许您在 XML 中自然地表达您的布局,而无需进行疯狂的代码更改。

您可能会说:但我希望我的 ExoPlayer 不必在每次方向更改时停止、准备和重新启动。好消息是有办法解决这个问题。

只需创建一个 ExoPlayer,在第一次加载时准备好它,然后在每个新的 activity 实例中继续使用该实例(存储在静态或其他单例中)。您可以将旧的 activity 与它分离,并在准备就绪后重新连接一个新的。

如果 ExoPlayer 的工作方式与 MediaPlayer 类似,那么这应该都可以。