How to make PlayerView full screen in landscape mode when used in MotionLayout

Tags: , , , ,



I want to make it possible to make the PlayerView in landscape mode full screen but I can’t make it work. So far, I have tried to set the playerView layout params programmatically when configuration changes to landscape mode, but it still isn’t working.

Layout that I have created

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/player_motion_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_collapseMode="parallax"
    app:layoutDescription="@xml/vod_player_scene"
    app:viewToDetectTouch="@id/top_player_container">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/top_player_container"
        android:layout_width="match_parent"
        android:layout_height="280dp"
        android:background="#272727"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="280dp"
        android:focusable="true"
        app:controller_layout_id="@layout/exo_playback_control_view_vod"
        app:fastforward_increment="10000"
        app:hide_on_touch="true"
        app:layout_constrainedWidth="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:resize_mode="fixed_width"
        app:rewind_increment="10000"
        app:show_timeout="2000" />

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="@id/playerView"
        app:layout_constraintEnd_toEndOf="@id/playerView"
        app:layout_constraintStart_toStartOf="@id/playerView"
        app:layout_constraintTop_toTopOf="@id/playerView" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/image_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:alpha="0"
        app:layout_constraintBottom_toBottomOf="@id/top_player_container"
        app:layout_constraintEnd_toStartOf="@id/image_clear"
        app:layout_constraintTop_toTopOf="@id/top_player_container"
        app:srcCompat="@drawable/ic_play_arrow_32dp"
        app:tint="@color/white" />

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/image_clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:alpha="0"
        android:background="?attr/selectableItemBackgroundBorderless"
        app:layout_constraintBottom_toBottomOf="@id/top_player_container"
        app:layout_constraintEnd_toEndOf="@id/top_player_container"
        app:layout_constraintTop_toTopOf="@id/top_player_container"
        app:srcCompat="@drawable/ic_clear_32dp"
        app:tint="@color/white" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/video_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:ellipsize="end"
        android:fontFamily="@font/montserrat_semi_bold"
        android:maxLines="1"
        android:textColor="@color/white"
        app:layout_constraintBottom_toBottomOf="@id/top_player_container"
        app:layout_constraintEnd_toStartOf="@id/image_play"
        app:layout_constraintStart_toEndOf="@id/playerView"
        app:layout_constraintTop_toTopOf="@id/top_player_container"
        tools:text="Blade Runner" />

    <FrameLayout
        android:id="@+id/recyclerview_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/video_club_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/top_player_container" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview_front"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/video_club_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/top_player_container" />

    <ProgressBar
        android:id="@+id/recyclerView_progressView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="@id/recyclerview_front"
        app:layout_constraintStart_toStartOf="@id/recyclerview_front"
        app:layout_constraintTop_toTopOf="@id/recyclerview_front" />

</androidx.constraintlayout.motion.widget.MotionLayout>

And programatically, I am doing it this way (see below code)

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        int newOrientation = newConfig.orientation;

        if (newOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            MotionLayout.LayoutParams params = (MotionLayout.LayoutParams)
                    getPlayerView().getLayoutParams();
            params.width = params.MATCH_PARENT;
            params.height = params.MATCH_PARENT;
            getPlayerView().setLayoutParams(params);
        } else {

        }
    }

Also in Manifest.xml I have declared activity as

    <activity
         android:name=".main.MainActivity"       
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
         android:label="@string/app_name"
         android:theme="@style/MainTheme"
         android:windowSoftInputMode="adjustPan" />

Let me know if you need anything else to share with you. Thanks in advance.

Answer

To be able to change any of the views that have MotionLayout as parent, we should work with MotionScene.

What I did to fix this problem, I created two functions, one to make playerView width and height to MATCH_PARENT and the other to reset it to previous state (when screen orientation back to portrait).

private void setPlayerToMatchHeight() {
    ConstraintSet expandedSet = getMotionLayout().getConstraintSet(R.id.expanded);
    ConstraintSet.Constraint topPlayerContainerSet = expandedSet.getConstraint(R.id.top_player_container);
    topPlayerContainerSet.layout.mHeight = ViewGroup.LayoutParams.MATCH_PARENT;
}

private void setPlayerTo16x9dimensionRatio() {
    ConstraintSet expandedSet = getMotionLayout().getConstraintSet(R.id.expanded);
    ConstraintSet.Constraint topPlayerContainerSet = expandedSet.getConstraint(R.id.top_player_container);
    topPlayerContainerSet.layout.mHeight = 0;
    topPlayerContainerSet.layout.dimensionRatio = "16:9";
}

And then, in onConfigurationChanged, based on newOrientation, I call these functions respectively.



Source: stackoverflow