package com.ydl.media.view
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager
import android.widget.*
import com.ydl.media.R
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.OnPlayerEventListener
import com.ydl.media.audio.model.Music
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_image.transform.GlideRoundTransform
import java.util.*
import java.util.concurrent.CopyOnWriteArraySet
class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
private var mTouchStartX: Float = 0.toFloat()
private var mTouchStartY: Float = 0.toFloat()
private var mCurrX: Float = 0.toFloat()
private var mCurrY: Float = 0.toFloat()
private var playState: ImageView? = null
private var mAudioLayout: LinearLayout? = null
private var mInfoLayout: RelativeLayout? = null
private var playClose: ImageView? = null
private var playHead: ImageView? = null
private var titleView: TextView? = null
private var nameView: TextView? = null
private var currentPlayingTimeView: TextView? = null
private var durationView: TextView? = null
private var mTouchSlop: Int = 0
private var time: Int = 0
private var allTime: Int = 0
private var isMove: Boolean = false
private var wm: WindowManager? = null
//此wmParams为获取的全局变量,用以保存悬浮窗口的属性
var wmParams = WindowManager.LayoutParams()
private var myHandler: Handler? = null
private val UPDATE_VIEW_STATE = 1
private val UPDATE_VIEW_COMPLETE = 2
private val UPDATE_PLAY_TIME = 3//更新播放时间
private var listeners: CopyOnWriteArraySet<FloatViewPlayListener> = CopyOnWriteArraySet()
private var mStateChangeListener: OnPlayerEventListener? = null
private var playData: HashMap<String, String> = hashMapOf<String, String>()
init {
init(context)
}
fun resetWm(context: Context) {
wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
wmParams = WindowManager.LayoutParams()
}
fun resetView() {
resetAudioView()
}
@SuppressLint("ClickableViewAccessibility")
private fun init(context: Context) {
wm = getContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager
mTouchSlop = (ViewConfiguration.get(getContext()).scaledTouchSlop + 8) * 3
val view = View.inflate(context, R.layout.item_playing_float_btn, this)
mAudioLayout = view.findViewById(R.id.ll_audio_layout)
mInfoLayout = view.findViewById(R.id.rl_info)
playHead = view.findViewById(R.id.play_head)
playState = view.findViewById(R.id.play_state)
playClose = view.findViewById(R.id.play_close)
titleView = view.findViewById(R.id.tv_title)
nameView = view.findViewById(R.id.tv_name)
currentPlayingTimeView = view.findViewById(R.id.tv_now_playing_time)
durationView = view.findViewById(R.id.tv_duration)
resetAudioView()
if (!TextUtils.isEmpty(AudioPlayer.get().playMusic?.coverPath)) {
GlideApp.with(context.applicationContext)
.load(AudioPlayer.get().playMusic?.coverPath)
.transform(GlideRoundTransform(context, 4))
.error(R.drawable.ico_play_float_pic)
.into(playHead!!)
}
myHandler = MyHandler()
playHead!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
titleView!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
nameView!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
playClose!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
for (listener in listeners) {
//数据重新设置回调
listener.onPauseClick()
}
this@PlayerFloatView.visibility = View.GONE
PlayerFloatHelper.removeView(mContext)
PlayerFloatHelper.playTempData.clear()
AudioPlayer.get().stopPlayer()
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
playState!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (AudioPlayer.get().isPlaying) {
playState!!.setImageResource(R.drawable.ico_yyfc_play)
AudioPlayer.get().playPause()
for (listener in listeners) {
//数据重新设置回调
listener.onPauseClick()
}
} else {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
AudioPlayer.get().playPause()
for (listener in listeners) {
//数据重新设置回调
listener.onStartClick()
}
}
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
if (mStateChangeListener == null) {
mStateChangeListener = object : OnPlayerEventListener {
override fun onComplete() {
myHandler?.sendEmptyMessage(UPDATE_VIEW_COMPLETE)
}
override fun onChange(music: Music) {
}
override fun onPlayerStart() {
}
override fun onPlayerPause() {
}
override fun onPublish(percent: Int, currentPosition: Long) {
this@PlayerFloatView.time = currentPosition.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
}
override fun onBufferingUpdate(percent: Int) {
}
override fun onPrepared(duration: Long) {
this@PlayerFloatView.allTime = duration.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
myHandler?.sendEmptyMessage(UPDATE_VIEW_STATE)
}
}
AudioPlayer.get().addOnPlayEventListener(mStateChangeListener!!)
}
}
private fun resetAudioView() {
if (!TextUtils.isEmpty(AudioPlayer.get().playMusic?.coverPath)) {
GlideApp.with(context.applicationContext)
.load(AudioPlayer.get().playMusic?.coverPath)
.transform(GlideRoundTransform(context, 4))
.error(R.drawable.ico_play_float_pic)
.into(playHead!!)
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.title)) {
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_FM) {
titleView!!.text = "心灵电台"
}
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_CONFIDE) {
titleView!!.text = "壹点倾诉,心灵寄语"
}
} else {
titleView!!.text = AudioPlayer.get().playMusic?.title
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.artist)) {
nameView!!.text = "壹点灵"
} else {
nameView!!.text = AudioPlayer.get().playMusic?.artist
}
mAudioLayout!!.visibility = View.VISIBLE
}
private fun getStringTime(time: Int): String {
if (time <= 0) return "00:00"
var min = time / 60000
var ss = (time - min * 60000) / 1000
var mm = "" + min
var SS = "" + ss
if (min < 10) {
mm = "0$mm"
}
if (ss < 10) {
SS = "0$ss"
}
return "$mm:$SS"
}
private fun updatePlayTime() {
currentPlayingTimeView?.text = getStringTime(time)
durationView?.text = getStringTime(allTime)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
//获取相对屏幕的坐标,即以屏幕左上角为原点
mCurrX = event.rawX
mCurrY = event.rawY - 25
Log.i("currP", "currX$mCurrX====currY$mCurrY")
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> updateViewPosition()
MotionEvent.ACTION_UP -> {
updateViewPosition()
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
return true
}
private fun updateViewPosition() {
//更新浮动窗口位置参数
wmParams.x = (mCurrX - mTouchStartX).toInt()
wmParams.y = (mCurrY - mTouchStartY).toInt()
wm!!.updateViewLayout(this, wmParams)
}
fun updatePlayState() {
if (AudioPlayer.get().isPlaying) {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
} else {
playState!!.setImageResource(R.drawable.ico_yyfc_play)
for (listener in listeners) {
listener.onPauseClick()
}
}
}
fun setPlayingState() {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
resetAudioView()
}
fun onDestroy() {
listeners.clear()
mStateChangeListener?.let { AudioPlayer.get().removeOnPlayEventListener(it) }
}
fun addFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.add(floatClickListener)
}
fun removeFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.remove(floatClickListener)
}
interface FloatViewPlayListener {
fun onPauseClick()
fun onStartClick()
fun onPlayFinish()
}
internal inner class MyHandler : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
UPDATE_VIEW_STATE -> updatePlayState()
UPDATE_VIEW_COMPLETE -> {
updatePlayState()
for (listener in listeners) {
//数据重新设置回调
listener.onPlayFinish()
}
}
UPDATE_PLAY_TIME -> {
updatePlayTime()
}
}
}
}
}