ExoPlayer控制器与视频重叠问题求助(附Fragment布局代码)
解决ExoPlayer控制器与视频内容重叠的问题
嘿,我看你遇到了ExoPlayer控制器和视频画面重叠的问题,结合你的布局代码,我来帮你梳理原因并给出可行的解决方案:
问题根源分析
- ScrollView的布局测量干扰:你把整个内容嵌套在ScrollView里,同时给PlayerView设置了
wrap_content高度,这会让ExoPlayer没法准确计算视频的实际显示高度,最终导致控制器和视频内容挤在一起。 - 默认控制器的悬浮特性:PlayerView自带的控制器默认是悬浮在视频画面上层的,如果视频高度没被正确计算,重叠问题就更容易出现。
解决方案
方案1:移除不必要的ScrollView(优先推荐)
如果你的页面内容(视频+文本+按钮)高度不会超过屏幕,直接去掉ScrollView就好,这样ConstraintLayout能正常测量PlayerView的高度:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.exoplayer2.ui.PlayerView android:id="@+id/playerView_step_video" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" <!-- 设置视频宽高比,比如16:9,让高度自动适配 --> app:layout_constraintDimensionRatio="16:9"/> <TextView android:id="@+id/textView_step_description" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:layout_constraintEnd_toEndOf="@+id/playerView_step_video" app:layout_constraintStart_toStartOf="@+id/playerView_step_video" app:layout_constraintTop_toBottomOf="@+id/playerView_step_video" /> <Button android:id="@+id/button_next_step" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="@string/next_step" app:layout_constraintStart_toStartOf="@+id/textView_step_description" app:layout_constraintTop_toBottomOf="@+id/textView_step_description" /> </android.support.constraint.ConstraintLayout>
方案2:保留ScrollView并调整布局参数
如果必须保留ScrollView,需要给ScrollView添加fillViewport="true",同时让PlayerView通过宽高比自动计算高度:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <android.support.constraint.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.exoplayer2.ui.PlayerView android:id="@+id/playerView_step_video" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintDimensionRatio="16:9" /> <TextView android:id="@+id/textView_step_description" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:layout_constraintEnd_toEndOf="@+id/playerView_step_video" app:layout_constraintStart_toStartOf="@+id/playerView_step_video" app:layout_constraintTop_toBottomOf="@+id/playerView_step_video" /> <Button android:id="@+id/button_next_step" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="@string/next_step" app:layout_constraintStart_toStartOf="@+id/textView_step_description" app:layout_constraintTop_toBottomOf="@+id/textView_step_description" /> </android.support.constraint.ConstraintLayout> </ScrollView>
方案3:让控制器显示在视频下方(彻底避免重叠)
如果你希望控制器不再悬浮在视频上,而是固定在视频下方,可以创建自定义控制器布局res/layout/custom_exo_controller.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 视频画面区域 --> <SurfaceView android:id="@id/exo_surface_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <!-- 控制器操作栏 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="8dp" android:background="#CC000000"> <ImageButton android:id="@id/exo_play" style="@style/ExoMediaButton.Play"/> <ImageButton android:id="@id/exo_pause" style="@style/ExoMediaButton.Pause"/> <TextView android:id="@id/exo_position" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:paddingLeft="4dp"/> <SeekBar android:id="@id/exo_progress" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:paddingLeft="4dp" android:paddingRight="4dp"/> <TextView android:id="@id/exo_duration" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:paddingRight="4dp"/> </LinearLayout> </LinearLayout>
然后在PlayerView里引用这个自定义布局:
<com.google.android.exoplayer2.ui.PlayerView ... app:controller_layout_id="@layout/custom_exo_controller"/>
额外小提示
- 尽量使用最新版本的ExoPlayer,旧版本可能存在布局测量的小bug;
- 如果视频加载后仍有重叠,可以在代码里监听
Player.EventListener的onVideoSizeChanged事件,手动调整PlayerView的高度。
内容的提问来源于stack exchange,提问作者Louise L.
相关产品推荐
相关产品推荐

