Изменение положения MediaController при вращении

Я пытаюсь изменить динамическую привязку MediaController на изменения ориентации. И после всех моих попыток это не работает по мере необходимости.

Возможно, вы могли бы указать на мою ошибку.

В нескольких словах:

Портретный режим:

  • weightSum = 1.
  • SurfaceView вес: 0,4
  • MediaController и HorizontalScrollView вес: 0,6
  • MediaController всегда видимый и не скрывающий

Ландшафтный режим:

  • SurfaceView вес: 0.0 (полный экран)

  • 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) Когда пейзаж: создайте другой mediaController и привяжите его к корневому представлению (не работает):

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

2) Когда пейзаж: измените якорь предыдущего 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);
    }
}

Итак, как я могу изменить привязку MediaController на SurfaceView динамически в режиме LANDSCAPE?

P.S. Скажите, нужен ли еще какой-то код.

Ответы

Ответ 1

Поскольку вы переопределяете onConfigurationChanged, я предполагаю, что это означает, что активность не позволяет Android управлять своими изменениями ориентации и вместо этого выбирать делать все сами. Это, как правило, не очень хорошая идея, и в настоящее время вы столкнулись с болью этого решения.: - (

Если я могу сделать рекомендацию: пусть Android управляет жизненным циклом вашей деятельности и использует разные макеты (например, layout-land/views.xml и layout-port/views.xml). Это позволит вам выражать свои макеты, естественно, в XML без необходимости делать сумасшедшие изменения кода.

Вероятно, вы собираетесь сказать: Но я хочу, чтобы мой ExoPlayer не должен был останавливаться, готовиться и перезапускаться при каждом изменении ориентации. Хорошая новость заключается в том, что есть способ обойти это.

Просто создайте один ExoPlayer, подготовьте его при первой загрузке и продолжайте использовать один экземпляр (хранящийся в статическом или некотором другом синглете) с каждым новым экземпляром действия. Вы можете отделить старую активность от нее и снова прикрепить ее, когда она готова.

Если ExoPlayer работает аналогично MediaPlayer, тогда все должно работать нормально.