播放器主view
IeltsMediaPlayer.kt
class IeltsMediaPlayer (context: Context, attrs: AttributeSet? = null) : BaseWidget(context,attrs){
/**
* 视频播放器view
*/
var playerView:KoolVideoView?=null
/**
* 所有视频上层UI的父类,需要时add进去
*/
var controlParent:ControllerView?=null
/**
* 返回按钮
*/
var mBackArrow: ImageView?=null
/**
* 配置类,所有外界传出的东西通过此配置拿到
*/
var mPlayerConfig:PlayerConfig?=null
//---------下面是所有视频上显示的视图-start
private var vScreenController:VScreenController?=null
private var hScreenController:HScreenController?=null
private var loading:PlayerLoadingView?=null
private var seekMonitor:SeekingMonitorView?=null
private var volumn:GestureVolumn?=null
private var brightness:GestureBrightness?=null
private var netError:PlayerNetErrorView?=null
private var complete:PlayCompleteView?=null
//---------下面是所有视频上显示的视图-end
var matchRLParams:RelativeLayout.LayoutParams?=null
var matchRLParamsChild:RelativeLayout.LayoutParams?=null
var matchRLHWrapParams:RelativeLayout.LayoutParams?=null
var matchFLParams:RelativeLayout.LayoutParams?=null
//配置
private var mLogLevel: Int = 2
//真实屏幕尺寸
private var mRealWidth:Int=0
private var mRealHeight:Int=0
//-----------标志位 start
private var isFullScreen:Boolean=false
//标识 是否有横向或者竖向的控制view正在显示
private var isScreenControlShowing:Boolean=false
/**
* 标志 当前正在展示的view类型
* 对应的是上面的这几个view
*/
private var showViewType:ShowViewType = ShowViewType.Empty
private var isPause:Boolean=false
//-----------标志位 end
//定时器 Disposable,用于更新播放器进度
var disposable: Disposable?=null
//重新播放回调
var replay:()->Unit={}
//播放下一个回调
var playNext:()->Unit={}
//上传进度到服务器
var uploadProgress:()->Unit={}
//初始化进度开始时间
var initProgress:()->Unit={}
//3s自动小时handler
var dismissHandler= Handler()
var runnable:Runnable= Runnable {
if (isScreenControlShowing){
removeAllChildView()
}
}
override fun initView() {
//初始化后面用的到的params
matchRLParams=RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT)
matchRLParams?.centerInParent()
matchRLParamsChild=RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT)
matchRLParamsChild?.centerInParent()
matchRLHWrapParams=RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT)
matchFLParams=RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT)
//初始化控件
playerView = view?.findViewById(R.id.playerView)
controlParent=view?.findViewById(R.id.controlParent)
mBackArrow=view?.findViewById(R.id.mBackArrow)
//初始化竖屏控制区域
vScreenController= VScreenController(context,null)
vScreenController?.layoutParams=matchRLParamsChild
vScreenController?.toFullScreen={
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE.also { (context as AbsPlayerActivity?)?.requestedOrientation = it }
toFullScreen()
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED.also { (context as AbsPlayerActivity?)?.requestedOrientation = it }
}
vScreenController?.pauseOrPlayClick={
if(playerView?.isPlaying ==true){
pauseVideo()
}else{
startVideo()
}
}
vScreenController?.seekTo={
playerView?.seekTo(it)
}
//初始化横屏控制区域
hScreenController= HScreenController(context,null)
hScreenController?.layoutParams=matchRLParamsChild
hScreenController?.toHalfScreen={
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT.also { (context as AbsPlayerActivity?)?.requestedOrientation = it }
toHalfScreen()
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED.also { (context as AbsPlayerActivity?)?.requestedOrientation = it }
}
hScreenController?.pauseOrPlayClick={
if(playerView?.isPlaying ==true){
pauseVideo()
}else{
startVideo()
}
}
hScreenController?.seekTo={
playerView?.seekTo(it)
}
//初始化网络错误
netError = PlayerNetErrorView(context,null)
netError?.layoutParams=matchRLParamsChild
//初始化进度监听view
seekMonitor = SeekingMonitorView(context,null)
seekMonitor?.layoutParams=matchRLParamsChild
seekMonitor?.seekTo={
playerView?.seekTo(it)
}
//初始化loading View
loading = PlayerLoadingView(context,null)
loading?.layoutParams=matchRLParamsChild
//初始化调整声音的view
volumn = GestureVolumn(context)
volumn?.layoutParams=matchRLParamsChild
//初始化调整亮度的view
brightness = GestureBrightness(context)
brightness?.layoutParams=matchRLParamsChild
//初始化 播放完成的view
complete = PlayCompleteView(context)
complete?.layoutParams=matchRLParamsChild
complete?.replay={
replay()
}
complete?.playNext={
playerView?.pause()
playNext()
}
}
override fun initInnerEvent() {
mBackArrow?.setOnClickListener {
v->
mPlayerConfig?.mActivity?.finish()
}
controlParent?.setGestureListener(object:ControllerView.OnControlEventListener{
override fun onTap(i: Int) {
//如果当前展示v or h 屏幕控制view中则点击移除
if(isScreenControlShowing){
removeAllChildView()
}else{
//如果当前展示为空时点击重建新的h or v 控制view
if(showViewType==ShowViewType.Empty){
removeAllChildView()
isScreenControlShowing=true
showControlView()
}
}
}
override fun onTouchMove(direction: Int, movedX: Float, movedY: Float) {
if (direction == ControllerView.OnControlEventListener.REGION_LEFT) {
adjustBrightness(movedY)
} else if (direction == ControllerView.OnControlEventListener.REGION_RIGHT) {
adjustVolumn(movedY)
} else if (direction == ControllerView.OnControlEventListener.REGION_CENTER) {
adjustSeekStart(movedX)
}
}
override fun onTouchUp(i: Int) {
if(showViewType==ShowViewType.SeekMonitorView){
seekMonitor?.adjustSeekEnd()
}
removeAllChildView()
}
})
disposable = Observable.interval(0, 1, TimeUnit.SECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
if(!isPause){
//更新当前正在播放时间
vScreenController?.updateProgress(playerView?.currentPosition?:0)
hScreenController?.updateProgress(playerView?.currentPosition?:0)
}
}
}
override fun getLayoutId()= R.layout.view_ielts_player
fun getMediaPlayerControl()=playerView
fun initPlayerConfig(playerConfig: PlayerConfig){
this.mPlayerConfig=playerConfig
getRealScreenWidth()
initVideoView()
}
/**
* 移除controlParent中所有子view的方法,切记在做与 isScreenControlShowing
* 和showType相关处理的时候记得要先执行此方法,否则会出现程序执行顺序异常
*/
private fun removeAllChildView(){
isScreenControlShowing=false
showViewType = ShowViewType.Empty
controlParent?.removeAllViews()
}
private fun initVideoView() {
if (playerView != null) {
playerView?.setToken(mPlayerConfig?.mToken)
playerView?.setCacheEnable(true)
playerView?.setCacheDir(getCacheDir())
playerView?.setOnBufferingUpdateListener(mOnBufferingUpdateListener)
playerView?.setOnCompletionListener(mOnCompletionListener)
playerView?.setOnErrorListener(mOnErrorListener)
playerView?.setOnPreparedListener(mOnPreparedListener)
playerView?.setOnInfoListener(mOnInfoListener)
playerView?.enableBackgroundPlay(true)
}
toHalfScreen()
}
fun setCacheDir(cacheDir: String?) {
if (playerView != null) {
playerView?.setCacheDir(cacheDir)
}
}
/**
* 初始化视频为竖屏
*/
fun toHalfScreen(){
val halfLayoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
mPlayerConfig?.mActivity?.resources?.getDimensionPixelSize(R.dimen.player_height)?:RelativeLayout.LayoutParams.WRAP_CONTENT
)
this.playerView?.layoutParams = halfLayoutParams
this.controlParent?.layoutParams = halfLayoutParams
//设置当前容器控件半屏
layoutParams=matchRLHWrapParams
}
private fun toFullScreen(){
val params1 = if (mRealHeight/mRealWidth.toFloat() <= 16.toFloat() / 9) {
// 屏幕宽高比 <= 16:9
RelativeLayout.LayoutParams(mRealHeight, mRealHeight * 9 / 16)
} else {
RelativeLayout.LayoutParams(mRealWidth * 16 / 9, mRealWidth)
}
params1.centerInParent()
this.playerView?.layoutParams = params1
this.controlParent?.layoutParams = params1
//设置当前容器控件全屏
layoutParams=matchRLParams
}
/**
* 获取屏幕真实宽高
*/
fun getRealScreenWidth() {
val display = mPlayerConfig?.mActivity?.windowManager?.getDefaultDisplay()
val realMetrics = DisplayMetrics()
display?.getRealMetrics(realMetrics)
mRealWidth = realMetrics.widthPixels
mRealHeight = realMetrics.heightPixels
}
/**
* ------------------------------------ activity related end -------------------------------------------------
*/
/**
* 播放
*/
fun play(uri: Uri?, titleName: String, showController: Boolean) {
// currentTitle = titleName
playerView?.setVideoURI(uri)
hScreenController?.setTitle(titleName)
showLoadingView()
loading?.showPreLoading()
}
/**
* ------------------------------------ initial player event listener start -------------------------------------------------
*/
private val mOnPreparedListener =
IMediaPlayer.OnPreparedListener { mp ->
var duration = getMediaPlayerControl()?.duration?:0
vScreenController?.setTotalTime(duration)
hScreenController?.setTotalTime(duration)
mPlayerConfig?.mediaPlayListener?.mPrepared(mp)
vScreenController?.showPlaying()
hScreenController?.showPlaying()
//当前显示加载中的话则移除
if(showViewType==ShowViewType.LoadingView){
removeAllChildView()
}
}
private val mOnBufferingUpdateListener =
IMediaPlayer.OnBufferingUpdateListener { mp, percent -> }
private val mOnInfoListener =
IMediaPlayer.OnInfoListener { mp, what, extra ->
mPlayerConfig?.mediaPlayListener?.mInfo(mp, what, extra)
when (what) {
KoolMediaPlayer.MEDIA_INFO_NETWORK_BANDWIDTH -> {
if(showViewType==ShowViewType.LoadingView){
loading?.updateLoadingSpeed(what,extra)
}
}
KoolMediaPlayer.MEDIA_INFO_BUFFERING_START -> {
if(showViewType!=ShowViewType.LoadingView){
showLoadingView()
}
loading?.showBuffering()
}
KoolMediaPlayer.MEDIA_INFO_BUFFERING_END -> {
if(showViewType==ShowViewType.LoadingView){
removeAllChildView()
}
}
KoolMediaPlayer.MEDIA_INFO_NETWORK_CACHE_BUFFING -> {
if(isFullScreen){
hScreenController?.updateSecondCache(extra)
}else{
hScreenController?.updateSecondCache(extra)
}
}
KoolMediaPlayer.MEDIA_INFO_BUFFERING_TIMEOUT, KoolMediaPlayer.MEDIA_INFO_BUFFERING_MAXFREQ ->
{
Log.i("--->","b")
showNetErrorView()
}
else -> {
}
}
false
}
private val mOnCompletionListener =
IMediaPlayer.OnCompletionListener { mp ->
//播放中断网会奇怪的走播放完成回调,故在此做相应的判断处理
if (NetworkUtil.isNetAvailable(context)) {
mPlayerConfig?.mediaPlayListener?.mCompletion(mp)
vScreenController?.showPlayEnd()
hScreenController?.showPlayEnd()
showPlayCompleteView()
} else { //需要先暂停,否则进度条会自动走到百分之百。
pauseVideo()
Log.i("--->","a")
showNetErrorView()
}
}
private val mOnErrorListener =
IMediaPlayer.OnErrorListener { iMediaPlayer, what, extra, tips ->
val errorEvent = mPlayerConfig?.mediaPlayListener?.mError(iMediaPlayer, what, extra, tips)
if (errorEvent != null) {
BaseApplication.toast(errorEvent.errorText)
} else {
BaseApplication.toast("what:$what extra:$extra")
}
true
}
/**
* ------------------------------------ player event listener end -------------------------------------------------
*/
fun onResume() {
}
fun ismIsOnPause(): Boolean {
return isPause
}
/**
* MediaController
*/
fun getCurrentTime(): Int {
return playerView?.currentPosition?:0
}
fun getTotalTime(): Int {
return return playerView?.duration?:0
}
/**
* ------------------------------------ activity related start -------------------------------------------------
*/
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return if (isFullScreen) {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT.also { (context as AbsPlayerActivity?)?.requestedOrientation = it }
true
} else {
(context as AbsPlayerActivity?)?.finish()
true
}
}
return false
}
fun onPause() {
pauseVideo()
}
fun onDestroy() {
if(disposable?.isDisposed==false){
disposable?.dispose()
}
dismissHandler.removeCallbacks(runnable)
clearVideoView()
if (playerView != null) {
playerView?.stopPlayback()
playerView = null
}
mPlayerConfig = null
}
private fun clearVideoView() {
controlParent?.removeAllViews()
playerView?.let {
it.setOnPreparedListener(null)
it.setOnInfoListener(null)
it.setOnErrorListener(null)
it.setOnCompletionListener(null)
it.setOnBufferingUpdateListener(null)
}
}
fun onScreenRotate(configuration: Configuration?) {
if(isScreenControlShowing){
controlParent?.removeAllViews()
}
if(configuration?.orientation==Configuration.ORIENTATION_LANDSCAPE){//横屏
isFullScreen=true
mBackArrow?.visibility = GONE
toFullScreen()
}else if(configuration?.orientation==Configuration.ORIENTATION_PORTRAIT){//竖屏
isFullScreen=false
mBackArrow?.visibility = VISIBLE
toHalfScreen()
}
}
/**
* 开始播放
* 更新按钮状态
* 2018/01/24 特殊情况(来电/分享)暂停/开始使用
*/
fun startVideo() {
isPause=false
initProgress()
playerView?.start()
vScreenController?.showPlaying()
hScreenController?.showPlaying()
}
/**
* 暂停播放
* 更新按钮状态
* 2018/01/24 特殊情况暂停/开始使用
*/
fun pauseVideo() {
isPause=true
uploadProgress()
playerView?.pause()
vScreenController?.showPause()
hScreenController?.showPause()
}
fun hidePlayCompleteView() {
// if (mPlayCompleteView != null) {
// mPlayCompleteView.hideMonitorView()
// }
}
fun hideMonitorView() {
// if (mMonitorVew != null) {
// mMonitorVew.hideMonitorView()
// }
}
/**
* 初始化断网监听器
* @param listener
*/
fun initNetError(listener: OnClickListener?) {
if (netError != null) {
netError?.initListener(listener)
}
}
fun setmIsOnPause(pause: Boolean) {
// this.mIsOnPause = pause
}
fun refreshCurrentPlay() {
// if (controlParent != null) {
// controlParent.refreshCurrentPlay()
// }
}
/**
* 调整播放进度
*/
private fun adjustSeekStart(movedX: Float) {
if(showViewType!=ShowViewType.SeekMonitorView){
showSeekMonitor()
seekMonitor?.initMonitorView(playerView?.currentPosition?:0,playerView?.duration?:1)
}
seekMonitor?.seekStart(movedX)
}
/**
* 调整音量大小
*/
private fun adjustVolumn(f: Float) {
if(showViewType!=ShowViewType.VolumnView){
showVolumn()
}
if (playerView?.audioVolumeMagX?:0 > 0) {
playerView?.audioVolumeMagX = 2
}
volumn?.adjustVolume(mPlayerConfig?.mActivity, f)
}
/**
* 调整屏幕亮度
*/
private fun adjustBrightness(f: Float) {
if(showViewType!=ShowViewType.BrightnessView){
showBrightNess()
}
brightness?.adjustBrightness(mPlayerConfig?.mActivity, f)
}
fun showPlayCompleteView() {
removeAllChildView()
showViewType=ShowViewType.CompleteView
controlParent?.addView(complete)
}
fun showVolumn(){
removeAllChildView()
showViewType=ShowViewType.VolumnView
controlParent?.addView(volumn)
}
fun showBrightNess(){
removeAllChildView()
showViewType=ShowViewType.BrightnessView
controlParent?.addView(brightness)
}
fun showSeekMonitor(){
removeAllChildView()
showViewType=ShowViewType.SeekMonitorView
controlParent?.addView(seekMonitor)
}
fun showControlView(){
dismissHandler.removeCallbacks(runnable)
if(isFullScreen){
showHControlView()
}else{
showVControlView()
}
dismissHandler.postDelayed(runnable, 3000) //3000毫秒后执行
}
fun showLoadingView(){
removeAllChildView()
showViewType=ShowViewType.LoadingView
controlParent?.addView(loading)
}
fun showNetErrorView(){
removeAllChildView()
showViewType=ShowViewType.NetErrorView
controlParent?.addView(netError)
}
fun showVControlView(){
showViewType=ShowViewType.VScreenView
controlParent?.addView(vScreenController)
}
fun showHControlView(){
showViewType=ShowViewType.HScreenView
controlParent?.addView(hScreenController)
}
}
view_ielts_player.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/black">
<org.koo.mediaplayer.KoolVideoView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.koo.ieltspro2019.player.ui.ControllerView
android:id="@+id/controlParent"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/mBackArrow"
android:layout_width="34dp"
android:layout_height="34dp"
android:padding="5dp"
android:layout_marginTop="22dp"
android:layout_marginLeft="15dp"
android:src="@drawable/icon_player_back" />
</RelativeLayout>
其中playerView是安卓具体播放器,其他view都是上层显示
所有控制view的父类 ControllerView.java
他处理接收用户在视频界面的点击滑动手指抬起等操作,并把相关结果传递给子类接口
public class ControllerView extends RelativeLayout {
private static final String TAG = "ControllerView";
private static float X_TOLERANCE = 0.0f;
private static float Y_TOLERANCE = 0.0f;
private DisplayInformationFetcher mDisplayInformationFetcher;
private DisplayMetrics mDisplayMetrics;
private boolean mDownLeftRegion = false;
private boolean mDownRightRegion = false;
private OnControlEventListener mGestureListener;
private boolean mMoved = false;
private boolean mMovedCenter = false;
private boolean mMovedLeft = false;
private boolean mMovedRight = false;
private float mTouchStartY = -1.0f;
private float mX = 0.0f;
private float mY = 0.0f;
public interface OnControlEventListener {
int REGION_CENTER = 2;
int REGION_LEFT = 0;
int REGION_RIGHT = 1;
void onTap(int i);
void onTouchMove(int i, float f, float f2);
void onTouchUp(int i);
}
public ControllerView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
init();
}
public ControllerView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
public ControllerView(Context context) {
super(context);
init();
}
private void init() {
this.mDisplayInformationFetcher = DisplayInformationFetcher.getInstance(getContext().getApplicationContext());
this.mDisplayMetrics = this.mDisplayInformationFetcher.getDisplayMetrics();
Y_TOLERANCE = this.mDisplayMetrics.density * 10.0f;
X_TOLERANCE = this.mDisplayMetrics.density * 10.0f;
setFocusable(true);
setFocusableInTouchMode(true);
setClickable(true);
}
public void setGestureListener(OnControlEventListener onControlEventListener) {
this.mGestureListener = onControlEventListener;
}
@Override
@SuppressLint({"ClickableViewAccessibility"})
public boolean onTouchEvent(MotionEvent motionEvent) {
if (!isClickable()) {
return false;
}
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
this.mTouchStartY = motionEvent.getY();
touchStart(motionEvent.getX(), motionEvent.getY());
} else if (this.mTouchStartY >= 0.0f && this.mTouchStartY < ((float) 10)) {
return false;
} else {
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
this.mTouchStartY = -1.0f;
touchMove(motionEvent.getX(), motionEvent.getY());
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
touchUp(motionEvent.getX(), motionEvent.getY());
this.mTouchStartY = -1.0f;
}
}
return true;
}
private void touchStart(float getX, float getY) {
int screenWidth = this.mDisplayInformationFetcher.getScreenWidth();
this.mX = getX;
this.mY = getY;
this.mMovedLeft = false;
this.mMovedRight = false;
this.mMovedCenter = false;
if (this.mX <= ((float) (screenWidth / 2))) {
this.mDownLeftRegion = true;
} else if (this.mX >= ((float) (screenWidth - (screenWidth / 2)))) {
this.mDownRightRegion = true;
}
}
private void touchMove(float getX, float getY) {
float f3 = getX - this.mX;
float f4 = getY - this.mY;
float abs = Math.abs(f3);
float abs2 = Math.abs(f4);
if (abs2 > Y_TOLERANCE && ((abs2 > abs || this.mMovedLeft || this.mMovedRight) && !this.mMovedCenter)) {
if (this.mDownLeftRegion) {
this.mMovedLeft = true;
if (this.mGestureListener != null) {
this.mGestureListener.onTouchMove(OnControlEventListener.REGION_LEFT, f3, f4);
}
this.mMoved = true;
this.mX = getX;
this.mY = getY;
}
if (this.mDownRightRegion) {
this.mMovedRight = true;
if (this.mGestureListener != null) {
this.mGestureListener.onTouchMove(OnControlEventListener.REGION_RIGHT, f3, f4);
}
this.mMoved = true;
this.mX = getX;
this.mY = getY;
}
} else if (abs <= X_TOLERANCE) {
} else {
if ((abs >= abs2 || this.mMovedCenter) && !this.mMovedLeft && !this.mMovedRight) {
this.mMovedCenter = true;
if (this.mGestureListener != null) {
this.mGestureListener.onTouchMove(OnControlEventListener.REGION_CENTER, f3, f4);
}
this.mMoved = true;
}
}
}
private void touchUp(float lastX, float lastY) {
if (this.mMoved) {
if (this.mGestureListener != null) {
if (this.mMovedLeft) {
this.mGestureListener.onTouchUp(OnControlEventListener.REGION_LEFT);
} else if (this.mMovedRight) {
this.mGestureListener.onTouchUp(OnControlEventListener.REGION_RIGHT);
} else if (this.mMovedCenter) {
this.mGestureListener.onTouchUp(OnControlEventListener.REGION_CENTER);
}
}
} else if (this.mGestureListener != null) {
this.mGestureListener.onTap(OnControlEventListener.REGION_CENTER);
}
this.mMoved = false;
this.mDownLeftRegion = false;
this.mDownRightRegion = false;
}
}
竖屏显示view VScreenController.kt
class VScreenController(context: Context, attrs: AttributeSet? = null) :BaseWidget(context,attrs) {
private var mPause: ImageView? = null
private var ivFullscreen: ImageView? = null
private var mSeekBar: MarkSeekBar? = null
private var mCurTime:TextView? = null
private var mSplit:TextView? = null
private var mEndTime:TextView? = null
var toFullScreen:() -> Unit={}
var pauseOrPlayClick:()->Unit={}
var seekTo:(position:Int)->Unit={}
var mTotalTime:Int=0
var isDragStart = false
override fun initView() {
mPause = view?.findViewById(R.id.iv_pause)
mSeekBar = view?.findViewById(R.id.sb_progress)
mCurTime = view?.findViewById(R.id.tv_cur_time)
mSplit = view?.findViewById(R.id.iv_split)
mEndTime = view?.findViewById(R.id.tv_end_time)
ivFullscreen = view?.findViewById(R.id.ivFullscreen)
}
override fun initInnerEvent() {
mPause?.setOnClickListener{
pauseOrPlayClick()
}
ivFullscreen?.setOnClickListener{
toFullScreen()
}
mSeekBar?.setOnProgressChangedListener(SeekBarChangeEvent())
}
inner class SeekBarChangeEvent : OnProgressChangedListener {
override fun onProgressChanged(
signSeekBar: MarkSeekBar,
progress: Float,
fromUser: Boolean
) {
isDragStart = true
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(progress.toInt())
}
override fun getProgressOnActionUp(signSeekBar: MarkSeekBar, progress: Float) {
seekTo(progress.toInt())
// 个别机型(vivo)单击进度条时按下状态没有置回,手动置回状态
if (mSeekBar?.isPressed ==true) {
mSeekBar?.isPressed = false
}
isDragStart = false
}
}
fun setTotalTime(totalTime:Int){
mTotalTime = totalTime
mSeekBar?.max=totalTime.toFloat()
mEndTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
}
fun updateProgress(position:Int) {
if(!isDragStart){
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(position)
if (mSeekBar != null && mTotalTime > 0) {
mSeekBar?.progress = position.toFloat()
}
}
}
fun updateSecondCache(cacheTime: Int,mTotalTime:Int) {
if (mSeekBar != null && mTotalTime > 0) {
mSeekBar?.setCacheProgress((cacheTime * 1000).toFloat())
}
}
fun showPlaying(){
mPause?.setImageResource(R.drawable.player_pause_01)
}
fun showPause(){
mPause?.setImageResource(R.drawable.player_pause_16)
}
/**
* 播放完成展示
*/
fun showPlayEnd(){
mSeekBar?.progress = mSeekBar?.max ?:100.toFloat()
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
mEndTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
}
override fun getLayoutId() = R.layout.player_v_controller
}
竖屏显示view布局 player_v_controller.xml
package com.koo.ieltspro2019.player.view
import android.content.Context
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.TextView
import com.koo.android.view.basewidget.BaseWidget
import com.koo.ieltspro2019.R
import com.koo.ieltspro2019.player.ui.utils.DKTimeFormatter
import com.koo.ieltspro2019.view.MarkSeekBar
import com.koo.ieltspro2019.view.MarkSeekBar.OnProgressChangedListener
class VScreenController(context: Context, attrs: AttributeSet? = null) :BaseWidget(context,attrs) {
private var mPause: ImageView? = null
private var ivFullscreen: ImageView? = null
private var mSeekBar: MarkSeekBar? = null
private var mCurTime:TextView? = null
private var mSplit:TextView? = null
private var mEndTime:TextView? = null
var toFullScreen:() -> Unit={}
var pauseOrPlayClick:()->Unit={}
var seekTo:(position:Int)->Unit={}
var mTotalTime:Int=0
var isDragStart = false
override fun initView() {
mPause = view?.findViewById(R.id.iv_pause)
mSeekBar = view?.findViewById(R.id.sb_progress)
mCurTime = view?.findViewById(R.id.tv_cur_time)
mSplit = view?.findViewById(R.id.iv_split)
mEndTime = view?.findViewById(R.id.tv_end_time)
ivFullscreen = view?.findViewById(R.id.ivFullscreen)
}
override fun initInnerEvent() {
mPause?.setOnClickListener{
pauseOrPlayClick()
}
ivFullscreen?.setOnClickListener{
toFullScreen()
}
mSeekBar?.setOnProgressChangedListener(SeekBarChangeEvent())
}
inner class SeekBarChangeEvent : OnProgressChangedListener {
override fun onProgressChanged(
signSeekBar: MarkSeekBar,
progress: Float,
fromUser: Boolean
) {
isDragStart = true
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(progress.toInt())
}
override fun getProgressOnActionUp(signSeekBar: MarkSeekBar, progress: Float) {
seekTo(progress.toInt())
// 个别机型(vivo)单击进度条时按下状态没有置回,手动置回状态
if (mSeekBar?.isPressed ==true) {
mSeekBar?.isPressed = false
}
isDragStart = false
}
}
fun setTotalTime(totalTime:Int){
mTotalTime = totalTime
mSeekBar?.max=totalTime.toFloat()
mEndTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
}
fun updateProgress(position:Int) {
if(!isDragStart){
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(position)
if (mSeekBar != null && mTotalTime > 0) {
mSeekBar?.progress = position.toFloat()
}
}
}
fun updateSecondCache(cacheTime: Int,mTotalTime:Int) {
if (mSeekBar != null && mTotalTime > 0) {
mSeekBar?.setCacheProgress((cacheTime * 1000).toFloat())
}
}
fun showPlaying(){
mPause?.setImageResource(R.drawable.player_pause_01)
}
fun showPause(){
mPause?.setImageResource(R.drawable.player_pause_16)
}
/**
* 播放完成展示
*/
fun showPlayEnd(){
mSeekBar?.progress = mSeekBar?.max ?:100.toFloat()
mCurTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
mEndTime?.text = DKTimeFormatter.getInstance().stringForTime(mTotalTime)
}
override fun getLayoutId() = R.layout.player_v_controller
}