Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Motion Layout OnSwipe Disables Clicks on YoutubePlayer (YoutubePlayer API)

I have a YoutubePlayer playing a video in my Motion Layout. I want to implement this youtube-like motion https://developer.android.com/training/constraint-layout/motionlayout/examples#youtube-like_motion

The issue here is that in the example provided above they accomplish the animation with an ImageView instead of a YoutubePlayer interface. But unfortunately, the youtube player interface seems to 'overrides' the click listeners and only allows clicks, not swipes. (This is my deduction).

I wonder how it is implemented in the youtube application. If anybody can answer me, please do. I need this in my app.

I've raised an issue, please check it out. https://issuetracker.google.com/issues/162155197

This is what I've tried:

  1. When setting touchRegionId to a view that's in front or behind the youtube player, clicks for the interface are disabled totally. Animation works though. I see no solution to this option because I think this behavior is by design.

  2. When setting limitBoundsTo to a view, it does its job. It limits the OnSwipe action region to such view boundaries. This works exactly as I need to UNTIL THE YOUTUBE PLAYER INTERFACE IS INITIALIZED. Right after it's initialized, OnSwipe is not detected anymore and the interface only listens for clicks, which enables you to pause the video for example. If the limit bound to view is bigger than the youtube interface, I can sill swipe on the remainings of the view. But the youtube interface won't listen to swipes. Maybe the interface does not support swipes?

  3. I've tried setting none of the above. Just plain OnSwipe with the drag direction. The swipe works everywhere before initializing youtube. When it's initialized the pixels being used by the youtube player interface stop listening for swipes, they only listen for clicks.

Taking 2. and 3. into account, I think this is a problem of the interface itself. Whatever suggestion you have, please let me know. Thank you.

This is my Motion Layout:

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blackBackground"
    android:nestedScrollingEnabled="false"
    app:layoutDescription="@xml/activity_main_scene"
    app:motionDebug="SHOW_ALL">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/player_background"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:touchscreenBlocksFocus="false"
        android:clickable="false"
        android:background="#000000"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/main_player"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/player_background"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/player_background" />

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

This is my activity_main_scene xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/openYoutubePlayer">
        <Constraint
            android:id="@id/player_background"
            android:layout_width="match_parent"
            android:layout_height="240dp"
            android:elevation="0dp">
            <CustomAttribute
                app:attributeName="backgroundColor"
                app:customColorValue="#000000" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/closeYoutubePlayer">
        <Constraint
            android:id="@id/player_background"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:elevation="4dp">
            <CustomAttribute
                app:attributeName="backgroundColor"
                app:customColorValue="@color/blackBackground" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/bottomYoutubePlayer">
        <Constraint
            android:id="@id/main_player"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@id/player_background"
            app:layout_constraintLeft_toLeftOf="@id/player_background"
            app:layout_constraintTop_toTopOf="@id/player_background" />
        <Constraint
            android:id="@id/player_background"
            android:layout_width="0dp"
            android:layout_height="54dp"
            app:layout_constraintBottom_toTopOf="@id/nav_view"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@id/openYoutubePlayer"
        app:constraintSetStart="@id/closeYoutubePlayer"
        app:duration="500" />

    <Transition
        android:id="@+id/youtubePlayerIsOpened"
        app:constraintSetEnd="@id/bottomYoutubePlayer"
        app:motionInterpolator="linear"
        app:constraintSetStart="@id/openYoutubePlayer"
        app:duration="500">
        <OnSwipe
            app:dragDirection="dragUp"
            app:touchRegionId="@id/player_background"
            app:touchAnchorId="@id/player_background"/>
    </Transition>

</MotionScene>

EDIT: YOUTUBE INITIALIZATION ADDED

val youtubePlayerSupportFragment = YouTubePlayerSupportFragmentX.newInstance()
            supportFragmentManager.beginTransaction()
                .add(R.id.main_player, youtubePlayerSupportFragment).commit()
            youtubePlayerSupportFragment.initialize(
                resources.getString(R.string.API_KEY),
                object : YouTubePlayer.OnInitializedListener {
                    override fun onInitializationSuccess(
                        p0: YouTubePlayer.Provider?,
                        p1: YouTubePlayer?,
                        p2: Boolean
                    ) {
                        p1?.loadVideo(incomingLink)
                        currentLink = incomingLink
                        youtubePlayer = p1
                    }

                    override fun onInitializationFailure(
                        p0: YouTubePlayer.Provider?,
                        p1: YouTubeInitializationResult?
                    ) {
                        layoutUtils.createToast(
                            applicationContext,
                            "Error al iniciar Youtube"
                        )
                    }
                })
like image 628
Lheonair Avatar asked Nov 16 '22 07:11

Lheonair


1 Answers

This is an issue with complex motion layout scenes. To use onClick and onSwipe on the same transition, you will need to:

  1. Handle onSwipe from the motion scene transition

  2. Handle onClick from a sub class of motion layout

  3. In the sub class of MotionLayout (Custom View), override these 2 methods:

class MyMotionLayout @JvmOverloads constructor(context: Context):MotionLayout(context) {

       override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
           //Check if we have MotionEvent.ACTION_UP while MotionEvent.ACTION_MOVE<0.5
           // i.e ..this was a click
           if(ev==MotionEvent.ACTION_UP){
               return true
           }
           return false
       }
       override fun onTouchEvent(event: MotionEvent): Boolean {
           // Here we actually handle the touch event 
           // This method will only be called if the touch event was intercepted in
           // onInterceptTouchEvent
           callOnClick() 
      
       }
   }
like image 152
D Lad Avatar answered May 16 '23 05:05

D Lad