Motion Layout OnSwipe 禁止点击 YoutubePlayer (YoutubePlayer API)

Posted

技术标签:

【中文标题】Motion Layout OnSwipe 禁止点击 YoutubePlayer (YoutubePlayer API)【英文标题】:Motion Layout OnSwipe Disables Clicks on YoutubePlayer (YoutubePlayer API) 【发布时间】:2020-11-15 14:39:12 【问题描述】:

我有一个 YoutubePlayer 在我的 Motion Layout 中播放视频。我想实现这个youtube-like motion https://developer.android.com/training/constraint-layout/motionlayout/examples#youtube-like_motion

这里的问题是,在上面提供的示例中,他们使用 ImageView 而不是 YoutubePlayer 界面来完成动画。但不幸的是,youtube 播放器界面似乎“覆盖”了点击监听器,只允许点击,不允许滑动。 (这是我的推论)。

我想知道它是如何在 youtube 应用程序中实现的。如果有人可以回答我,请做。我在我的应用中需要这个。

我提出了一个问题,请检查一下。 https://issuetracker.google.com/issues/162155197

这是我尝试过的:

    touchRegionId 设置为 youtube 播放器前面或后面的视图时,该界面的点击完全被禁用。动画虽然有效。我认为这个选项没有解决方案,因为我认为这种行为是设计使然。

    limitBoundsTo 设置为视图时,它会完成它的工作。它将OnSwipe 操作区域限制为此类视图边界。这完全符合我的需要直到 YouTube 播放器界面初始化。初始化后,OnSwipe 不再被检测到,界面只监听点击,例如,您可以暂停视频。如果绑定到视图的限制大于 youtube 界面,我可以在视图的剩余部分上滑动。但是 youtube 界面不会听滑动。也许界面不支持滑动?

    我已尝试不设置上述任何一项。只是简单的 OnSwipe 与拖动方向。在初始化 youtube 之前,刷卡无处不在。初始化 youtube 播放器界面使用的像素停止监听滑动时,它们只监听点击。

考虑到2.和3.,我认为这是界面本身的问题。无论你有什么建议,请告诉我。谢谢。

这是我的动态布局:

<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_
    android:layout_
    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_
        android:layout_
        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_
        android:layout_
        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>

这是我的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_
            android:layout_
            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_
            android:layout_
            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_
            android:layout_
            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_
            android:layout_
            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>

编辑:添加了 YouTube 初始化

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"
                        )
                    
                )

【问题讨论】:

请出示 YouTube 播放器的初始化代码 完成!:) 请检查一下 Ок,谢谢。您将整个 YouTube 播放器片段放在 main_player 容器中。但是,如果您查看 YouTube 应用程序本身,那么播放器只占用了布局的一部分。尝试使用嵌套在具有 TextView 和操作按钮的单个布局容器中的播放器制作片段。我想如果你给这样一个普通的容器添加一个监听器,一切都会好起来的。 感谢您的建议。我最初在片段中实现了 youtube 播放器界面。在这个片段中,youtube 播放器界面只使用了整个布局的一小部分。问题依旧。 如何为您的 youtubeview/youtube 片段添加自定义触摸处理?您可以在其中任何一个上设置一个 onTouch 侦听器,并且几乎可以做任何您想做的事情。你试过走这条路吗? 【参考方案1】:

这是复杂运动布局场景的问题。要在同一个转换中使用 onClick 和 onSwipe,您需要:

    从运动场景过渡处理 onSwipe

    从动作布局的子类处理 onClick

    在MotionLayout(自定义视图)的子类中,重写这2个方法:

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() 
      
       
   

【讨论】:

以上是关于Motion Layout OnSwipe 禁止点击 YoutubePlayer (YoutubePlayer API)的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 自定义插入动作按钮 onSwipe

在 onswipe jquery 中使用参数调用外部函数

禁止viewpager不可滚动

HDU 1035 [Robot Motion] 模拟 记忆

u3d 逐个点运动,路径运动。 U3d one by one, path motion.

android 如何禁止scrollview 滚动