前言
本篇博文讲解的内容是使用EXOPlayer应该如何进行自定义UI界面,达到自己满意的项目效果,主要讲解的是自定义这方面的思路,该怎么入手,确定方向。
切入点
我们按照自定义从浅及深的程度来进行,以自定义视频播放控制view为切入点(在EXOPlayer中,播放界面和播控view的自定义思路一样)。
通过EXOPlayer的源码分析,我们知道,原来的播放控制view是PlaybackControlView效果如下:
那现在我们对它默认的播放控制view样式不满意,我们想修改,该怎么做呢?
我们可以新建一个Layout 布局文件命名为exo_playback_control_view,然后我们就可以在这个布局文件里面设计我们想要的布局样式.比如我们的布局设计成如下的样子:
<FrameLayout 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.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/player_bottom_bg">
<TextView
android:id="@+id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:textColor="@android:color/white"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="@+id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:textColor="@android:color/white"
app:layout_constraintRight_toRightOf="parent" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_height="26dp"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="@id/exo_position"
app:layout_constraintLeft_toRightOf="@id/exo_position"
app:layout_constraintRight_toLeftOf="@id/exo_duration"
app:layout_constraintTop_toTopOf="@id/exo_position"
app:played_color="#FFDE81"
app:unplayed_color="@android:color/black"
app:buffered_color="@android:color/darker_gray"/>
<ImageView
android:id="@+id/exo_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play_btn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/exo_progress" />
<ImageView
android:id="@+id/exo_pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause_btn"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/exo_progress" />
<android.support.constraint.Guideline
android:id="@+id/gl"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
/>
<ImageView
android:id="@+id/exo_rew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pre_btn"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toLeftOf="@id/gl"
app:layout_constraintTop_toTopOf="@id/exo_play" />
<ImageView
android:id="@+id/exo_ffwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/next_btn"
android:layout_marginStart="8dp"
app:layout_constraintLeft_toRightOf="@id/gl"
app:layout_constraintTop_toTopOf="@id/exo_play" />
</android.support.constraint.ConstraintLayout>
</FrameLayout>
这里我用了ConstraintLayout布局,关于ConstraintLayout布局的使用可以去Android ConstraintLayout布局详解 这里了解。
相应的view效果如下:
通过这样我们就可以改变PlaybackControlView的UI了,这里要注意几个问题。
- 控件的id不能随便起,要与exoPlayer原来PlaybackControlView的布局控件id,名称一致。如:
exo_play –>播放
exo_pause –>暂停
exo_rew –>后退
exo_ffwd –>前进
exo_prev –>上一个
exo_next –>下一个
exo_repeat_toggle –>重复模式开关
exo_duration –>视频总时长
exo_position –>当前播放位置
exo_progress –>播放进度 - 布局的控件数量可以少于上面列表所提到的 数量(比如上一个,下一个这个功能我不想要,就可以不写,也就不会展示出来),不能超过上面所提到列表,不能出现上面没包含的含义。比如说:想在控制布局上添加一个展示当前播放视频来源的icon。那就实现不了。
我们接着说,可能你会疑问,自定义的布局名称就一定要是exo_playback_control_view吗?事实是,不一定。可以随便填的,不过此刻需要在SimpleExoPlayerView控件中添加一个:
app:controller_layout_id="布局id"
属性。来表明该SimpleExoPlayerView所对应的PlaybackControlView的布局哪个。
到这关于轻中度自定义PlaybackControlView 布局的内容就讲个差不多了,对了SimpleExoPlayerView的默认进度条是一个自定义View,叫做DefaultTimeBar,可以通过xml设置他的颜色,高度,大小等等。比如我上面就通过了
app:played_color="#FFDE81"
app:unplayed_color="@android:color/black"
app:buffered_color="@android:color/darker_gray"
这三个属性,设置了他的播放过的精度条颜色,未播放的精度条颜色,以及缓存的进度条颜色。如果你想改变他的样式的话,可能会麻烦点需要实现TimeBar接口,实现对应的方法,以及各种逻辑,这块的话,可以看DefaultTimeBar的源码,仿写就好。
回过头来接着说,关于轻中度自定义PlaybackControlView 布局大概就这些点,同理,关于轻中度自定义SimpleExoPlayerView 布局即播放界面,也是跟自定义PlaybackControlView大致的思路,源码上有相关的介绍,这里就不细说了,很好理解。
上面说的是轻中度自定义界面,那如果我们的定制化需求很高,上面的自定义程度不满足我们该怎么办呢?那就高程度自定义UI呗。我们可以重写PlaybackControlView这个播控类,和SimpleExoPlayerView这个播放类,虽然重写比较繁琐,但是逻辑并不难。重写的时候吧原来PlaybackControlView、SimpleExoPlayerView这两个类的代码拷过去,然后自己改吧改吧就可以了。这两个类内部的代码量不大,逻辑也不难,大家可以自己去看源码,动手试试。这边我就简单的举个小例子证明一下我上面说的高度定制的思路的正确性~~
比如上面我提到了,我想添加一个用来展示当前播放视频来源的icon。这个控件含义在不属于上面我提到的那些范围中。我该怎么做呢?
第一步。在上面布局xml文件的基础上添加一个ImageView。代码如下:
<ImageView
android:id="@+id/exo_site"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/video_sources_default"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
id名称为exo_site 不属于上面提到的那个列表里。
接着,重写PlaybackControlView类。
public class MyExoControlView extends FrameLayout {
//省略
...
mSite = findViewById(R.id.exo_site);
if (mSite != null) {
mSite.setOnClickListener(componentListener);
}
...
...//省略
} else if (mSite == view) {
Toast.makeText(getContext(), "mSite clicked", Toast.LENGTH_SHORT).show();
}
...
...//省略
}
我们实现了点击弹toast的显示效果。
接着重写SimpleExoPlayerView类。
public class MyExoPlayerView extends FrameLayout {
}
把类中出现的PlaybackControlView全都替换成MyExoControlView。
最后,把代码中,布局中SimpleExoPlayerView全部替换为MyExoPlayerView即可。我们看下实现效果:
我们看到右下角出现了我们想要的icon。
总结
本文讲解了关于EXOplayer的初中高三种自定义UI程度的方式,及实现思路。关于EXOPlayerUI的自定义基本上就是上面这样,最后高级定制需要重写相应的view这块内容,由于博文有限,这次就不细说了,有时间再认真写一份。