触摸ExoPlayer时Motion Layout动画失效问题求助
解决Motion Layout折叠动画与ExoPlayer控件的触摸冲突问题
嘿,我完全懂你遇到的这个麻烦——想保留ExoPlayer默认的控件交互,同时让Motion Layout的折叠动画在触摸PlayerView时正常触发对吧?这问题本质上是触摸事件的消费优先级冲突:ExoPlayer的PlayerView默认会把触摸事件吃掉来切换控件可见性,导致下层的MotionLayout根本没机会触发动画。
下面给你两个实用的解决方案,都不用关掉PlayerView的控制器:
方法一:自定义PlayerView,动态控制事件传递
我们可以自定义一个PlayerView子类,在触摸事件发生时先判断当前视图状态,再决定是自己处理事件还是让MotionLayout接手。
class CustomPlayerView(context: Context, attrs: AttributeSet?) : PlayerView(context, attrs) { override fun onTouchEvent(event: MotionEvent): Boolean { // 只在按下动作时做判断,避免干扰后续事件 if (event.action == MotionEvent.ACTION_DOWN) { // 检查当前是否处于展开状态(需要替换成你自己的状态判断逻辑) val motionLayout = parent as MotionLayout val isExpanded = motionLayout.currentState == R.id.state_expanded if (isExpanded) { // 如果是展开状态,允许父布局(MotionLayout)拦截触摸事件 parent.requestDisallowInterceptTouchEvent(false) } } // 最后交给PlayerView的默认逻辑处理 return super.onTouchEvent(event) } }
然后把布局里的com.google.android.exoplayer2.ui.PlayerView替换成你的CustomPlayerView就行。这个方法的好处是逻辑集中,完全可控。
方法二:监听控件可见性,动态切换事件拦截
另一种更轻量的方式是利用ExoPlayer的控制器可见性监听器,根据控件是否显示来决定是否让MotionLayout接收触摸事件:
playerView.setControllerVisibilityListener { visibility -> val motionLayout = findViewById<MotionLayout>(R.id.your_motion_layout_id) if (visibility == View.GONE) { // 当播放器控件隐藏时,允许MotionLayout拦截触摸事件 playerView.requestDisallowInterceptTouchEvent(false) } else { // 控件显示时,让PlayerView自己处理触摸(切换控件可见性) playerView.requestDisallowInterceptTouchEvent(true) } }
这个逻辑很直观:当用户看不到播放器控件时,触摸PlayerView就会触发MotionLayout的折叠动画;当控件显示时,触摸还是会切换控件的可见性,完美保留默认行为。
额外注意点
- 确保你的MotionLayout已经正确配置了折叠/展开的状态,并且设置了合适的触摸触发条件(比如
app:touchAnchorId、app:touchAnchorSide或者点击触发的transition)。 - 如果用方法一,
isExpanded()里的状态判断要和你MotionLayout里的状态ID对应,别写错了。
这样调整后,应该就能同时满足播放器控件的默认交互和折叠动画的触发需求啦!
内容的提问来源于stack exchange,提问作者The Urdu Tech
相关产品推荐
相关产品推荐

