Commit 8f1f52f0 by 王佳洋

1,音视频悬浮窗代码优化

2,音频播放页逻辑修正
parent 91a4261a
......@@ -91,7 +91,7 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
}
@Override
public void onChange(Music music) {
public void onLoad(Music music) {
onChangeImpl(music);
}
......
......@@ -3,7 +3,6 @@ package com.yidianling.course.coursePlay
import android.content.Intent
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.util.Log
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import com.alibaba.android.arouter.facade.annotation.Route
......@@ -61,9 +60,9 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
private val ROUTER_PARAMS = "routerParam"
private var mCourseId = 0 // 课程id
private var receiverPlayUrl: String? = null // 外部选中要播放的音/视频文件地址
private var isFromFloatView = false // 是否是悬浮窗进入
private var from: Int = 0
private var mReceiverPlayUrl: String? = null // 外部选中要播放的音/视频文件地址
private var mIsFromFloatView = false // 是否是悬浮窗进入
private var mFrom: Int = 0
private var mCourPlayBean: CourseMediaDetailBean? = null
private val mPlayList: ArrayList<CourseMediaBean> = ArrayList() // 播放列表
private var mCourseSpeedDialog: CourseSpeedDialog? = null
......@@ -113,20 +112,20 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
}
//正常跳转所传参数
mCourseId = it.getIntExtra("course_id", 0)
receiverPlayUrl = it.getStringExtra("coursePlayUrl")
isFromFloatView = it.getBooleanExtra("isFromFloatView", false)
if (!TextUtils.isEmpty(receiverPlayUrl) && isFromFloatView)
mReceiverPlayUrl = it.getStringExtra("coursePlayUrl")
mIsFromFloatView = it.getBooleanExtra("isFromFloatView", false)
if (!TextUtils.isEmpty(mReceiverPlayUrl) && mIsFromFloatView)
audio_play.mNonWifiTips = false
try {
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_COURSE
&& AudioPlayer.get().isPlaying
&& TextUtils.isEmpty(receiverPlayUrl)
&& audio_play.isPlaying()
&& TextUtils.isEmpty(mReceiverPlayUrl)
) {
receiverPlayUrl = AudioPlayer.get().playMusic?.path
mReceiverPlayUrl = audio_play.getAudioMusic()?.path
}
} catch (e: Exception) {
}
from = it.getIntExtra("from", 0)
mFrom = it.getIntExtra("from", 0)
if (mCourseId == 0) {
ToastUtil.toastShort("参数错误")
finish()
......@@ -179,11 +178,9 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
}
private fun togglePlaying(playPosition: Int) {
Log.d("wjy====", "mCurrentPosition -> $mCurrentPosition index -> $playPosition")
if (playPosition >= mPlayList.size || playPosition < 0) {
ToastUtil.toastShort("暂无内容")
} else if (mCurrentPosition != playPosition) {
Log.d("wjy====", "audio_play.play")
mCurrentPosition = playPosition
mCourPlayBean?.courseExtra?.let {
if (isCanPlay(it.isBuy)) audio_play.play(mCurrentPosition)
......@@ -194,7 +191,7 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
private fun isCanPlay(isBuy: Boolean): Boolean {
mPlayList.elementAtOrNull(mCurrentPosition)?.let {
if (!it.isDemo && !isBuy) {
if (AudioPlayer.get().isPlaying) AudioPlayer.get().pausePlayer()
if (audio_play.isPlaying()) audio_play.pausePlay()
buyCourseTipDialog()
} else if (it.mediaType == COURSE_AUDIO) {
return true
......@@ -221,9 +218,9 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
}
private fun showFloatView(): Boolean {
if (AudioPlayer.get().isPlaying && PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_COURSE) {
AudioPlayer.get().playMusic?.coverPath = mCourPlayBean?.courseExtra?.pic
AudioPlayer.get().playMusic?.artist = mCourPlayBean?.courseExtra?.doctorName
if (audio_play.isPlaying() && PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_COURSE) {
audio_play.getAudioMusic()?.coverPath = mCourPlayBean?.courseExtra?.pic
audio_play.getAudioMusic()?.artist = mCourPlayBean?.courseExtra?.doctorName
PlayerFloatHelper.playTempData.clear()
......@@ -276,10 +273,10 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
mCourPlayBean = bean
mPlayList.clear()
setPlayList(bean)
if (!TextUtils.isEmpty(receiverPlayUrl)) {
if (!TextUtils.isEmpty(mReceiverPlayUrl)) {
mCurrentPosition = mPlayList.indexOfLast {
TextUtils.equals(receiverPlayUrl, it.url) || TextUtils.equals(
receiverPlayUrl!!.replace(
TextUtils.equals(mReceiverPlayUrl, it.url) || TextUtils.equals(
mReceiverPlayUrl!!.replace(
"http",
"https"
), it.url
......@@ -312,7 +309,7 @@ class AudioPlayActivity : BaseMvpActivity<IAudioPlayContract.View, IAudioPlayCon
tv_list.setOnClickListener { listClick() }
iv_list.setOnClickListener { listClick() }
}
audio_play.setData(mCurrentPosition, convertToMusics(mPlayList), bean.courseExtra.isBuy, from)
audio_play.setData(mCurrentPosition, convertToMusics(mPlayList), bean.courseExtra.isBuy, mFrom)
}
private fun convertToMusics(list: List<CourseMediaBean>): ArrayList<Music> {
......
......@@ -62,11 +62,13 @@ class CourseServiceImp : ICourseService {
}
override fun startCoursePlayActivity(activity: Activity, courseId: Int, coursePlayUrl: String?, from: Int, mediaType: String?) {
val intent = if (COURSE_AUDIO.toString() == mediaType) {
Intent(activity, AudioPlayActivity::class.java)
} else {
Intent(activity, CoursePlayActivity::class.java)
}
// val intent = if (COURSE_AUDIO.toString() == mediaType) {
// Intent(activity, AudioPlayActivity::class.java)
// } else {
// Intent(activity, CoursePlayActivity::class.java)
// }
val intent = Intent(activity, AudioPlayActivity::class.java)
intent.putExtra("course_id", courseId)
intent.putExtra("coursePlayUrl", coursePlayUrl)
intent.putExtra("from", from)
......
package com.yidianling.course.widget
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.FrameLayout
import android.widget.SeekBar
......@@ -81,7 +83,7 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
if (playList.isEmpty()) return
setAutoNext(isAuto)
AudioPlayer.get().addPlayList(playList)
if (AudioPlayer.get().isPlaying) mNonWifiTips = false
if (isPlaying()) mNonWifiTips = false
if (RxNetTool.isWifi(context)) {
playAudio(from, playPosition, playList)
} else {
......@@ -101,9 +103,10 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
}
private fun playAudio(from: Int, playPosition: Int, playList: ArrayList<Music>) {
if (AudioPlayer.get().isPlaying && (from == 1 || from == 2)) {
if (isPlaying() && (from == 1 || from == 2)) {
if (TextUtils.equals(getCurrentUrl(), playList[playPosition].path)) {
updateView(playPosition)
seekbar.max = AudioPlayer.get().getDuration().toInt()
tv_duration.text = getStringTime(seekbar.max)
} else {
play(playPosition)
}
......@@ -112,16 +115,6 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
}
}
private fun updateView(playPosition: Int) {
if (AudioPlayer.get().isPlaying) {
seekbar.max = AudioPlayer.get().getDuration().toInt()
tv_end.text = getStringTime(seekbar.max)
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
}
}
}
/**
* 获取当前播放url
*/
......@@ -131,10 +124,7 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
fun play(index: Int) {
PlayerFloatHelper.playingType = PlayTypeEnum.PLAY_TYPE_COURSE
AudioPlayer.get().play(index)
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
}
AudioPlayer.get().load(index)
}
/**
......@@ -148,47 +138,41 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
}
}
override fun onChange(music: Music) {
@SuppressLint("SetTextI18n")
override fun onLoad(music: Music) {
displayPlayStatus(R.drawable.course_loading5, true)
seekbar.progress = 0
tv_start.text = "00:00"
}
override fun onPlayerStart() {
displayPlayStatus(R.drawable.course_pause)
}
override fun onPlayerPause() {
if (AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_pause)
} else {
displayPlayStatus(R.drawable.course_play)
}
override fun onPrepared(duration: Long) {
seekbar.max = duration.toInt()
tv_duration.text = getStringTime(seekbar.max)
mListener?.invoke(AudioPlayer.get().playPosition)
}
override fun onBufferingUpdate(percent: Int) {
seekbar.secondaryProgress = percent * seekbar.max / 100
}
override fun onPublish(percent: Int, currentPosition: Long) {
if (!mSeekBarIsTouch) {
displayPlayStatus(R.drawable.course_pause)
seekbar.progress = currentPosition.toInt()
tv_start.text = getStringTime(currentPosition.toInt())
}
}
override fun onBufferingUpdate(percent: Int) {
if (!AudioPlayer.get().isPlaying) {
displayPlayStatus(R.drawable.course_loading5, true)
}
seekbar.secondaryProgress = percent * seekbar.max / 100
}
override fun onPrepared(duration: Long) {
seekbar.max = duration.toInt()
tv_end.text = getStringTime(seekbar.max)
mListener?.invoke(AudioPlayer.get().playPosition)
override fun onComplete() {
}
override fun onComplete() {
if (AudioPlayer.get().isPlaying) {
override fun onPlayerPause() {
if (isPlaying()) {
displayPlayStatus(R.drawable.course_pause)
} else {
displayPlayStatus(R.drawable.course_play)
}
}
......@@ -230,4 +214,10 @@ class AudioPlayView(context: Context, attrs: AttributeSet?) :
AudioPlayer.get().setSpeed(speed)
}
fun isPlaying() = AudioPlayer.get().isPlaying
fun pausePlay() = AudioPlayer.get().pausePlayer()
fun getAudioMusic() = AudioPlayer.get().playMusic
}
\ No newline at end of file
......@@ -117,7 +117,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
fun play(index: Int) {
PlayerFloatHelper.playingType = PlayTypeEnum.PLAY_TYPE_COURSE
AudioPlayer.get().play(index)
AudioPlayer.get().load(index)
updateButton()
}
......@@ -140,7 +140,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
@SuppressLint("SetTextI18n")
override fun onChange(music: Music) {
override fun onLoad(music: Music) {
if (mContext != null) {
displayImage(com.yidianling.course.R.drawable.course_loading5,img_gif,true)
}
......
......@@ -11,7 +11,7 @@
<clip>
<shape>
<corners android:radius="3dp" />
<solid android:color="#ECF0F1" />
<solid android:color="@color/color_FAFAFF" />
</shape>
</clip>
</item>
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="375dp"
android:height="90dp"
android:viewportWidth="375"
android:viewportHeight="90">
<path
android:pathData="M0,0h375v90h-375z"
android:strokeWidth="1"
android:fillType="evenOdd"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:startY="0"
android:startX="187.5"
android:endY="90"
android:endX="187.5"
android:type="linear">
<item android:offset="0" android:color="#C7FFFFFF"/>
<item android:offset="0.45317963" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
</vector>
......@@ -36,7 +36,7 @@
android:minHeight="3dp"
android:progressDrawable="@drawable/course_seekbar"
android:thumb="@drawable/course_seekbar_dot"
tools:progress="0" />
android:progress="0" />
<TextView
android:id="@+id/tv_start"
......@@ -49,7 +49,7 @@
android:textColor="@android:color/white"/>
<TextView
android:id="@+id/tv_end"
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="00:00"
......
......@@ -26,11 +26,4 @@
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<View
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@drawable/mask"
app:layout_constraintBottom_toBottomOf="@id/recycler_list" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -591,7 +591,7 @@ public class FMDetailActivity extends BaseActivity implements View.OnClickListen
}
@Override
public void onChange(@NotNull Music music) {
public void onLoad(@NotNull Music music) {
}
......
......@@ -292,7 +292,7 @@ class MeditationFloatWindow(var mContext: Context) : FrameLayout(mContext) {
myHandler?.sendEmptyMessage(UPDATE_VIEW_COMPLETE)
}
override fun onChange(music: Music) {
override fun onLoad(music: Music) {
}
override fun onPlayerStart() {
......
......@@ -122,17 +122,14 @@ class AudioPlayer private constructor() {
fun init(context: Context) {
this.context = context.applicationContext
audioFocusManager = AudioFocusManager(context)
mediaPlayer = IjkMediaPlayer()
try {
(mediaPlayer as IjkMediaPlayer).setOption(
IjkMediaPlayer.OPT_CATEGORY_FORMAT,
"dns_cache_clear",
1
)
mediaPlayer = IjkMediaPlayer().also {
it.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1)
it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1)
}
} catch (e: Exception) {
LogUtil.e(e.message)
}
mediaPlayer!!.setOnPreparedListener {
if (isPreparing) {
if (autoSaveProgress) {
......@@ -217,7 +214,7 @@ class AudioPlayer private constructor() {
musicList.add(music)
playMode = PlayModeEnum.SINGLE
autoSaveProgress = isAutoSaveProgress
play(0)
load(0)
}
/**
......@@ -228,7 +225,7 @@ class AudioPlayer private constructor() {
musicList.add(music)
playMode = PlayModeEnum.SINGLE_LOOP
autoSaveProgress = false
play(0)
load(0)
}
/**
......@@ -240,20 +237,20 @@ class AudioPlayer private constructor() {
musicList.add(music)
position = musicList.size - 1
}
play(position)
load(position)
}
/**
* 播放第一首
*/
fun play() {
play(0)
load(0)
}
/**
* 加载指定索引的音乐
*/
fun play(index: Int) {
fun load(index: Int) {
var position = index
if (musicList.isEmpty()) {
return
......@@ -275,7 +272,7 @@ class AudioPlayer private constructor() {
mediaPlayer!!.prepareAsync()
state = STATE_PREPARING
for (listener in listeners) {
listener.onChange(music)
listener.onLoad(music)
}
if (isShowNotify) {
NotifyManager.get().showPlay(music)
......@@ -303,7 +300,7 @@ class AudioPlayer private constructor() {
} else {
stopPlayer()
for (listener in listeners) {
listener.onChange(playMusic!!)
listener.onLoad(playMusic!!)
}
}
}
......@@ -324,7 +321,7 @@ class AudioPlayer private constructor() {
startPlayer()
}
else -> {
play(playPosition)
load(playPosition)
}
}
}
......@@ -408,7 +405,7 @@ class AudioPlayer private constructor() {
PlayModeEnum.LIST_LOOP -> playPosition + 1
else -> playPosition + 1
}
play(position)
load(position)
}
/**
......@@ -424,7 +421,7 @@ class AudioPlayer private constructor() {
PlayModeEnum.LIST_LOOP -> playPosition - 1
else -> playPosition - 1
}
play(playPosition)
load(playPosition)
}
/**
......@@ -434,20 +431,24 @@ class AudioPlayer private constructor() {
*/
fun seekTo(percent: Int = -1, position: Long = -1) {
if (isPlaying || isPausing) {
var currentPosition = 0L
val duration = getDuration()
var currentPercent = 0
if (position != (-1).toLong()) {
val current = (currentPosition * 1.0).toFloat()
val du = mediaPlayer!!.duration.toFloat()
currentPercent = (current * 100 / du).toInt()
currentPosition = position
val currentPosition = if (position != -1L) {
val pos = when {
position > duration -> duration
position < 0 -> 0L
else -> position
}
currentPercent = (pos / duration).toInt()
pos
} else {
currentPosition = percent * mediaPlayer!!.duration / 100
currentPercent = when {
percent > 100 -> 100
percent < 0 -> 0
else -> percent
}
currentPercent * duration / 100
}
mediaPlayer!!.seekTo(currentPosition)
MediaSessionManager.get().updatePlaybackState()
if (autoSaveProgress) {
......
......@@ -10,26 +10,21 @@ import com.ydl.media.audio.model.Music
interface OnPlayerEventListener {
/**
* 切换歌曲
* 加载歌曲
*/
fun onChange(music: Music)
fun onLoad(music: Music)
/**
* 继续播放
* 开始播放
*/
fun onPlayerStart()
/**
* 暂停播放
*/
fun onPlayerPause()
/**
* 更新进度
* percent : 播放百分比
* currentPosition:当前播放位置
* 准备完成
*
* duration:音乐时长
*/
fun onPublish(percent: Int,currentPosition: Long)
fun onPrepared(duration:Long)
/**
* 缓冲百分比
......@@ -37,14 +32,19 @@ interface OnPlayerEventListener {
fun onBufferingUpdate(percent: Int)
/**
* 准备完成
*
* duration:音乐时长
* 更新进度
* percent : 播放百分比
* currentPosition:当前播放位置
*/
fun onPrepared(duration:Long)
fun onPublish(percent: Int,currentPosition: Long)
/**
* 单曲播放完成
*/
fun onComplete()
/**
* 暂停播放
*/
fun onPlayerPause()
}
......@@ -14,6 +14,7 @@ import com.ydl.media.audio.utils.CoverImageUtils
/**
* Created by haorui on 2019-10-27 .
* Des:
* 线控
*/
class MediaSessionManager private constructor() {
......
......@@ -6,11 +6,11 @@ import android.content.Intent
import android.graphics.PixelFormat
import android.graphics.Point
import android.os.Bundle
import androidx.core.view.ViewCompat
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import androidx.core.view.ViewCompat
import com.alibaba.android.arouter.launcher.ARouter
import com.ydl.media.audio.AudioPlayer
import com.yidianling.common.tools.RxImageTool
......@@ -82,11 +82,11 @@ class PlayerFloatHelper {
}
if (showingPageName != context::class.qualifiedName) {
mPlayerFloatView?.resetWm(context)
mPlayerFloatView?.resetLayoutParams()
addFloatToWm(context)
}
mPlayerFloatView?.resetView()
mPlayerFloatView?.resetFloatView()
mPlayerFloatView?.visibility = View.VISIBLE
mPlayerFloatView?.setPlayingState()
......@@ -153,7 +153,7 @@ class PlayerFloatHelper {
//获取WindowManager
wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
//设置LayoutParams(全局变量)相关参数
val wmParams = mPlayerFloatView?.wmParams
val wmParams = mPlayerFloatView?.mFloatViewParams
wmParams?.type = WindowManager.LayoutParams.TYPE_APPLICATION //设置window type
wmParams?.format = PixelFormat.RGBA_8888 //设置图片格式,效果为背景透明
//设置Window flag
......
......@@ -2,14 +2,12 @@ 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.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager
import android.widget.*
import android.widget.FrameLayout
import com.ydl.media.R
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.OnPlayerEventListener
......@@ -17,282 +15,82 @@ import com.ydl.media.audio.model.Music
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_image.transform.GlideRoundTransform
import com.ydl.ydlcommon.utils.statusBar.StatusBarUtil
import java.util.*
import kotlinx.android.synthetic.main.item_playing_float_btn.view.*
import java.util.concurrent.CopyOnWriteArraySet
import kotlin.math.abs
class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
class PlayerFloatView(private val ctx: Context) : FrameLayout(ctx) {
private var mTouchDownX: Float = 0.toFloat()
private var mTouchDownY: Float = 0.toFloat()
private var mTouchX: Float = 0.toFloat()
private var mTouchY: Float = 0.toFloat()
private var playState: ImageView? = 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 val mTouchSlop: Int = (ViewConfiguration.get(ctx).scaledTouchSlop + 8) * 3
private var time: Int = 0
private var allTime: Int = 0
private var isMove: Boolean = false
private val mWindowManager: WindowManager = ctx.getSystemService(Context.WINDOW_SERVICE) as WindowManager
//全局变量,用以保存悬浮窗口的属性
var mFloatViewParams = WindowManager.LayoutParams()
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 mListeners: CopyOnWriteArraySet<FloatViewPlayListener> = CopyOnWriteArraySet()
private var mStateChangeListener: OnPlayerEventListener? = null
private val mStatusBarHeight: Int = StatusBarUtil.getStatusBarHeight(mContext)
init {
init(context)
}
private val mStatusBarHeight: Int = StatusBarUtil.getStatusBarHeight(ctx)
fun resetWm(context: Context) {
wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
wmParams = WindowManager.LayoutParams()
}
fun resetView() {
resetAudioView()
fun resetLayoutParams() {
mFloatViewParams = WindowManager.LayoutParams()
}
@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)
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()
init {
View.inflate(context, R.layout.item_playing_float_btn, this)
resetFloatView()
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!!)
.into(play_head)
}
myHandler = MyHandler()
playHead!!.setOnTouchListener { _, event ->
mTouchX = event.rawX
mTouchY = event.rawY
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop || Math.abs(event.y - mTouchDownY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop ||
Math.abs(event.y - mTouchDownY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchDownY = 0f
mTouchDownX = mTouchDownY
}
cl.setOnClickListener {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
true
}
titleView!!.setOnTouchListener { _, event ->
mTouchX = event.rawX
mTouchY = event.rawY
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop || Math.abs(event.y - mTouchDownY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop ||
Math.abs(event.y - mTouchDownY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchDownY = 0f
mTouchDownX = mTouchDownY
}
play_close.setOnClickListener {
mListeners.forEach {
it.onPauseClick()
}
true
PlayerFloatHelper.removeView(ctx)
PlayerFloatHelper.playTempData.clear()
AudioPlayer.get().stopPlayer()
}
nameView!!.setOnTouchListener { _, event ->
mTouchX = event.rawX
mTouchY = event.rawY
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop || Math.abs(event.y - mTouchDownY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop ||
Math.abs(event.y - mTouchDownY) > mTouchSlop || isMove
) {
updateViewPosition()
} else {
if (!isMove) {
if (PlayerFloatHelper.isCanClick) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
}
isMove = false
mTouchDownY = 0f
mTouchDownX = mTouchDownY
play_state.setOnClickListener {
if (AudioPlayer.get().isPlaying) {
play_state.setImageResource(R.drawable.ico_yyfc_play)
AudioPlayer.get().playPause()
mListeners.forEach {
it.onPauseClick()
}
} else {
play_state.setImageResource(R.drawable.ico_yyfc_pause)
AudioPlayer.get().playPause()
mListeners.forEach {
it.onStartClick()
}
}
true
}
playClose!!.setOnTouchListener { _, event ->
mTouchX = event.rawX
mTouchY = event.rawY
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop || Math.abs(event.y - mTouchDownY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop ||
Math.abs(event.y - mTouchDownY) > 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
mTouchDownY = 0f
mTouchDownX = mTouchDownY
}
}
true
}
playState!!.setOnTouchListener { _, event ->
mTouchX = event.rawX
mTouchY = event.rawY
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop || Math.abs(event.y - mTouchDownY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchDownX) > mTouchSlop ||
Math.abs(event.y - mTouchDownY) > 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
mTouchDownY = 0f
mTouchDownX = mTouchDownY
}
}
true
}
if (mStateChangeListener == null) {
mStateChangeListener = object : OnPlayerEventListener {
override fun onComplete() {
myHandler?.sendEmptyMessage(UPDATE_VIEW_COMPLETE)
updatePlayState()
mListeners.forEach {
it.onPlayFinish()
}
}
override fun onChange(music: Music) {
override fun onLoad(music: Music) {
}
override fun onPlayerStart() {
......@@ -301,18 +99,17 @@ class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
override fun onPlayerPause() {
}
@SuppressLint("SetTextI18n")
override fun onPublish(percent: Int, currentPosition: Long) {
this@PlayerFloatView.time = currentPosition.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
tv_now_playing_time.text = getStringTime(currentPosition.toInt())
}
override fun onBufferingUpdate(percent: Int) {
}
@SuppressLint("SetTextI18n")
override fun onPrepared(duration: Long) {
this@PlayerFloatView.allTime = duration.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
myHandler?.sendEmptyMessage(UPDATE_VIEW_STATE)
updatePlayState()
}
}
AudioPlayer.get().addOnPlayEventListener(mStateChangeListener!!)
......@@ -320,52 +117,67 @@ class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
}
private fun resetAudioView() {
@SuppressLint("SetTextI18n")
fun resetFloatView() {
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!!)
.into(play_head)
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.title)) {
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_FM) {
titleView!!.text = "心灵电台"
tv_title.text = "心灵电台"
}
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_CONFIDE) {
titleView!!.text = "壹点倾诉,心灵寄语"
tv_title.text = "壹点倾诉,心灵寄语"
}
} else {
titleView!!.text = AudioPlayer.get().playMusic?.title
tv_title.text = AudioPlayer.get().playMusic?.title
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.artist)) {
nameView!!.text = "壹点灵"
tv_name.text = if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.artist)) {
"壹点灵"
} else {
nameView!!.text = AudioPlayer.get().playMusic?.artist
AudioPlayer.get().playMusic?.artist
}
tv_duration.text = " / ${getStringTime(AudioPlayer.get().getDuration().toInt())}"
}
private fun getStringTime(time: Int): String {
if (time <= 0) return "00:00"
var min = time / 60000
var ss = (time - min * 60000) / 1000
val min = time / 60000
val ss = (time - min * 60000) / 1000
var mm = "" + min
var SS = "" + ss
var m = "" + min
var s = "" + ss
if (min < 10) {
mm = "0$mm"
m = "0$m"
}
if (ss < 10) {
SS = "0$ss"
s = "0$ss"
}
return "$mm:$SS"
return "$m:$s"
}
private fun updatePlayTime() {
currentPlayingTimeView?.text = getStringTime(time)
durationView?.text = getStringTime(allTime)
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
mTouchDownY = ev.y
}
MotionEvent.ACTION_MOVE -> {
val moveY = ev.y
if (abs(moveY - mTouchDownY) > mTouchSlop) {
return true
}
}
MotionEvent.ACTION_UP -> {
mTouchDownY = 0f
}
}
return super.onInterceptTouchEvent(ev)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
......@@ -378,50 +190,50 @@ class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
mTouchDownX = event.x
mTouchDownY = event.y
}
MotionEvent.ACTION_MOVE -> updateViewPosition()
MotionEvent.ACTION_MOVE -> updateFloatViewPosition()
MotionEvent.ACTION_UP -> {
updateViewPosition()
updateFloatViewPosition()
mTouchDownY = 0f
mTouchDownX = mTouchDownY
}
}
return true
return super.onTouchEvent(event)
}
private fun updateViewPosition() {
private fun updateFloatViewPosition() {
//更新浮动窗口位置参数
wmParams.x = (mTouchX - mTouchDownX).toInt()
wmParams.y = (mTouchY - mTouchDownY - mStatusBarHeight).toInt()
wm!!.updateViewLayout(this, wmParams)
mFloatViewParams.x = (mTouchX - mTouchDownX).toInt()
mFloatViewParams.y = (mTouchY - mTouchDownY - mStatusBarHeight).toInt()
mWindowManager.updateViewLayout(this, mFloatViewParams)
}
fun updatePlayState() {
if (AudioPlayer.get().isPlaying) {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
play_state.setImageResource(R.drawable.ico_yyfc_pause)
} else {
playState!!.setImageResource(R.drawable.ico_yyfc_play)
for (listener in listeners) {
play_state.setImageResource(R.drawable.ico_yyfc_play)
for (listener in mListeners) {
listener.onPauseClick()
}
}
}
fun setPlayingState() {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
resetAudioView()
play_state.setImageResource(R.drawable.ico_yyfc_pause)
resetFloatView()
}
fun onDestroy() {
listeners.clear()
mListeners.clear()
mStateChangeListener?.let { AudioPlayer.get().removeOnPlayEventListener(it) }
}
fun addFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.add(floatClickListener)
mListeners.add(floatClickListener)
}
fun removeFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.remove(floatClickListener)
mListeners.remove(floatClickListener)
}
interface FloatViewPlayListener {
......@@ -433,21 +245,4 @@ class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
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()
}
}
}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cl"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginStart="15dp"
......@@ -22,7 +23,6 @@
android:id="@+id/play_head"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:src="@drawable/ico_play_float_pic"
app:layout_constraintBottom_toBottomOf="parent"
......@@ -59,23 +59,30 @@
<TextView
android:id="@+id/tv_now_playing_time"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@id/tv_title"
app:layout_constraintStart_toStartOf="@id/tv_title"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintTop_toBottomOf="@id/tv_name"
android:textColor="#BFBFBF"
android:textSize="10sp"
tools:text="00:06" />
<TextView
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBaseline_toBaselineOf="@id/tv_now_playing_time"
app:layout_constraintStart_toEndOf="@id/tv_now_playing_time"
android:textColor="#BFBFBF"
android:textSize="10sp"
tools:text=" / 30:28" />
<ImageView
android:id="@+id/play_state"
android:layout_width="30dp"
android:layout_width="57dp"
android:layout_height="30dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingStart="12dp"
android:paddingEnd="15dp"
android:scaleType="centerCrop"
android:src="@drawable/ico_yyfc_play"
app:layout_constraintBottom_toBottomOf="parent"
......
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_longAnimTime"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="0"
android:toYDelta="100%p"/>
</set>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_longAnimTime"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0"/>
</set>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment