Minor mpv-player UI fixes (#517)

* Condense code + bug fixes

* Add double tap to play/pause

* Fix few button highlights

* prevent controls auto fade when paused

* fix max of negative brightness bar
This commit is contained in:
Quickdesh 2022-04-13 19:26:48 +09:00 committed by GitHub
parent 494b2bb374
commit c703e1fa86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 394 additions and 323 deletions

View file

@ -23,23 +23,9 @@ class Gestures(
return true return true
} }
override fun onSingleTapUp(e: MotionEvent): Boolean {
if (e.y < height * 0.05F || e.y > height * 0.95F || e.x < width * 0.05F || e.x > width * 0.95F) return false
when {
e.x < width * 0.4F -> return false
e.x > width * 0.6F -> return false
else -> activity.toggleControls()
}
return true
}
override fun onSingleTapConfirmed(e: MotionEvent): Boolean { override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
if (e.y < height * 0.05F || e.y > height * 0.95F || e.x < width * 0.05F || e.x > width * 0.95F) return false if (e.y < height * 0.05F || e.y > height * 0.95F || e.x < width * 0.05F || e.x > width * 0.95F) return false
when { activity.toggleControls()
e.x < width * 0.4F -> activity.toggleControls()
e.x > width * 0.6F -> activity.toggleControls()
else -> return false
}
return true return true
} }
@ -50,20 +36,11 @@ class Gestures(
when { when {
e.x < width * 0.4F -> activity.doubleTapSeek(-interval, e) e.x < width * 0.4F -> activity.doubleTapSeek(-interval, e)
e.x > width * 0.6F -> activity.doubleTapSeek(interval, e) e.x > width * 0.6F -> activity.doubleTapSeek(interval, e)
else -> activity.doubleTapPlayPause()
} }
return true return true
} }
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
if (activity.isLocked) return false
if (e.y < height * 0.05F || e.y > height * 0.95F || e.x < width * 0.05F || e.x > width * 0.95F) return false
if (e.action == MotionEvent.ACTION_UP && e.x > width * 0.4F && e.x < width * 0.6F) {
activity.toggleControls()
return true
}
return false
}
override fun onScroll( override fun onScroll(
e1: MotionEvent, e1: MotionEvent,
e2: MotionEvent, e2: MotionEvent,

View file

@ -29,8 +29,8 @@ import android.view.View
import android.view.ViewAnimationUtils import android.view.ViewAnimationUtils
import android.view.WindowManager import android.view.WindowManager
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.SeekBar import android.widget.SeekBar
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.annotation.StringRes import androidx.annotation.StringRes
@ -198,9 +198,6 @@ class PlayerActivity :
private val animationHandler = Handler(Looper.getMainLooper()) private val animationHandler = Handler(Looper.getMainLooper())
// I spent like an hour trying to make the below 4 vals and functions, into one function. Failed miserably!
// All on you man, sorry
// Fade out seek text // Fade out seek text
private val seekTextRunnable = Runnable { private val seekTextRunnable = Runnable {
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation -> AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
@ -209,13 +206,6 @@ class PlayerActivity :
} }
} }
private fun showSeekText() {
animationHandler.removeCallbacks(seekTextRunnable)
binding.seekView.visibility = View.VISIBLE
animationHandler.postDelayed(seekTextRunnable, 500L)
}
// Fade out Volume Bar // Fade out Volume Bar
private val volumeViewRunnable = Runnable { private val volumeViewRunnable = Runnable {
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation -> AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
@ -224,13 +214,6 @@ class PlayerActivity :
} }
} }
private fun showVolumeView() {
animationHandler.removeCallbacks(volumeViewRunnable)
binding.volumeView.visibility = View.VISIBLE
animationHandler.postDelayed(volumeViewRunnable, 500L)
}
// Fade out Brightness Bar // Fade out Brightness Bar
private val brightnessViewRunnable = Runnable { private val brightnessViewRunnable = Runnable {
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation -> AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
@ -239,26 +222,50 @@ class PlayerActivity :
} }
} }
private fun showBrightnessView() {
animationHandler.removeCallbacks(brightnessViewRunnable)
binding.brightnessView.visibility = View.VISIBLE
animationHandler.postDelayed(brightnessViewRunnable, 500L)
}
// Fade out Player controls // Fade out Player controls
private val controlsViewRunnable = Runnable { private val controlsViewRunnable = Runnable {
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation -> AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
findViewById<RelativeLayout>(R.id.player_controls).startAnimation(fadeAnimation) if (!isLocked) {
binding.playerControls.visibility = View.GONE findViewById<LinearLayout>(R.id.controlsView).startAnimation(fadeAnimation)
binding.controlsView.visibility = View.GONE
} else {
findViewById<LinearLayout>(R.id.lockedView).startAnimation(fadeAnimation)
binding.lockedView.visibility = View.GONE
}
} }
} }
private fun showControlsView() { private fun showGestureView(type: String) {
animationHandler.removeCallbacks(controlsViewRunnable) val callback: Runnable
binding.playerControls.visibility = View.VISIBLE val itemView: LinearLayout
val delay: Long
when (type) {
"seek" -> {
callback = seekTextRunnable
itemView = binding.seekView
delay = 500L
}
"volume" -> {
callback = volumeViewRunnable
itemView = binding.volumeView
delay = 500L
}
"brightness" -> {
callback = brightnessViewRunnable
itemView = binding.brightnessView
delay = 500L
}
"controls" -> {
callback = controlsViewRunnable
itemView = if (!isLocked) binding.controlsView else binding.lockedView
delay = 3500L
}
else -> return
}
animationHandler.postDelayed(controlsViewRunnable, 1500L) animationHandler.removeCallbacks(callback)
itemView.visibility = View.VISIBLE
animationHandler.postDelayed(callback, delay)
} }
private val seekBarChangeListener = object : SeekBar.OnSeekBarChangeListener { private val seekBarChangeListener = object : SeekBar.OnSeekBarChangeListener {
@ -311,7 +318,10 @@ class PlayerActivity :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
window.navigationBarColor = 70000000 window.navigationBarColor = 70000000
} }
setVisibilities() setVisibilities()
showGestureView("controls")
player.initialize(applicationContext.filesDir.path) player.initialize(applicationContext.filesDir.path)
MPVLib.setOptionString("keep-open", "always") MPVLib.setOptionString("keep-open", "always")
player.addObserver(this) player.addObserver(this)
@ -408,19 +418,36 @@ class PlayerActivity :
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
if (isLocked) { if (isLocked) {
// Hide controls // Hide controls
binding.playerControls.isVisible = false binding.controlsView.isVisible = false
// Toggle unlock button if (!binding.lockedView.isVisible && !player.paused!!) showGestureView("controls")
binding.unlockBtn.isVisible = !binding.unlockBtn.isVisible else if (!binding.lockedView.isVisible && player.paused!!) binding.lockedView.visibility = View.VISIBLE
else {
animationHandler.removeCallbacks(controlsViewRunnable)
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
findViewById<LinearLayout>(R.id.lockedView).startAnimation(fadeAnimation)
binding.lockedView.visibility = View.GONE
}
}
} else { } else {
if(!binding.playerControls.isVisible) showControlsView() if (!binding.controlsView.isVisible && !player.paused!!) showGestureView("controls")
else { animationHandler.removeCallbacks(controlsViewRunnable); binding.playerControls.isVisible = false } else if (!binding.controlsView.isVisible && player.paused!!) binding.controlsView.visibility = View.VISIBLE
binding.unlockBtn.isVisible = false
else {
animationHandler.removeCallbacks(controlsViewRunnable)
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
findViewById<LinearLayout>(R.id.controlsView).startAnimation(fadeAnimation)
binding.controlsView.visibility = View.GONE
}
}
binding.lockedView.isVisible = false
} }
} }
private fun hideControls(hide: Boolean) { private fun hideControls(hide: Boolean) {
binding.playerControls.isVisible = !hide binding.controlsView.isVisible = !hide
} }
private fun showLoadingIndicator(visible: Boolean) { private fun showLoadingIndicator(visible: Boolean) {
@ -614,6 +641,37 @@ class PlayerActivity :
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
fun playPause(view: View) { fun playPause(view: View) {
player.cyclePause() player.cyclePause()
when {
player.paused!! -> animationHandler.removeCallbacks(controlsViewRunnable)
binding.controlsView.isVisible -> showGestureView("controls")
}
}
val playPauseRunnable = Runnable {
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
findViewById<ImageView>(R.id.playPauseView).startAnimation(fadeAnimation)
binding.playPauseView.visibility = View.GONE
}
}
fun doubleTapPlayPause() {
animationHandler.removeCallbacks(playPauseRunnable)
playPause(binding.playBtn)
if (!binding.controlsView.isVisible) {
when {
player.paused!! -> { binding.playPauseView.setImageResource(R.drawable.ic_pause_80dp) }
!player.paused!! -> { binding.playPauseView.setImageResource(R.drawable.ic_play_arrow_80dp) }
}
// if (binding.controlsView.isVisible) { binding.playPauseView.visibility = View.GONE; binding.playPauseView.setBackgroundColor(0x00000000) } else { binding.playPauseView.visibility = View.VISIBLE; binding.playPauseView.setBackgroundColor(0x70000000) }
AnimationUtils.loadAnimation(this, R.anim.fade_in_medium).also { fadeAnimation ->
findViewById<ImageView>(R.id.playPauseView).startAnimation(fadeAnimation)
binding.playPauseView.visibility = View.VISIBLE
}
animationHandler.postDelayed(playPauseRunnable, 500L)
} else binding.playPauseView.visibility = View.GONE
} }
fun doubleTapSeek(time: Int, event: MotionEvent? = null) { fun doubleTapSeek(time: Int, event: MotionEvent? = null) {
@ -630,7 +688,7 @@ class PlayerActivity :
val diffText = Utils.prettyTime(time, true) val diffText = Utils.prettyTime(time, true)
binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText) binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText)
showSeekText() showGestureView("seek")
} }
fun verticalScrollLeft(diff: Float) { fun verticalScrollLeft(diff: Float) {
@ -651,9 +709,8 @@ class PlayerActivity :
binding.brightnessText.text = finalBrightness.toString() binding.brightnessText.text = finalBrightness.toString()
binding.brightnessBar.progress = finalBrightness binding.brightnessBar.progress = finalBrightness
binding.brightnessBar.secondaryProgress = abs(finalBrightness) binding.brightnessBar.secondaryProgress = abs(finalBrightness)
if (finalBrightness >= 0) binding.brightnessImg.setImageResource(R.drawable.ic_brightness_positive_24dp) if (finalBrightness >= 0) { binding.brightnessImg.setImageResource(R.drawable.ic_brightness_positive_24dp); binding.brightnessBar.max = 100 } else { binding.brightnessImg.setImageResource(R.drawable.ic_brightness_negative_24dp); binding.brightnessBar.max = 75 }
else binding.brightnessImg.setImageResource(R.drawable.ic_brightness_negative_24dp) showGestureView("brightness")
showBrightnessView()
} }
fun verticalScrollRight(diff: Float) { fun verticalScrollRight(diff: Float) {
@ -666,7 +723,7 @@ class PlayerActivity :
binding.volumeBar.progress = newVolume binding.volumeBar.progress = newVolume
if (newVolume == 0) binding.volumeImg.setImageResource(R.drawable.ic_volume_none_24dp) if (newVolume == 0) binding.volumeImg.setImageResource(R.drawable.ic_volume_none_24dp)
else binding.volumeImg.setImageResource(R.drawable.ic_volume_high_24dp) else binding.volumeImg.setImageResource(R.drawable.ic_volume_high_24dp)
showVolumeView() showGestureView("volume")
} }
fun initSeek() { fun initSeek() {
@ -687,7 +744,7 @@ class PlayerActivity :
val diffText = Utils.prettyTime(newDiff, true) val diffText = Utils.prettyTime(newDiff, true)
binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText) binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText)
showSeekText() showGestureView("seek")
} }
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")

View file

@ -48,314 +48,334 @@
app:tint="?attr/colorAccent" /> app:tint="?attr/colorAccent" />
</LinearLayout> </LinearLayout>
<ImageButton <LinearLayout
android:id="@+id/unlockBtn" android:id="@+id/lockedView"
android:layout_width="48dp" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="match_parent"
android:src="@drawable/ic_lock_open_24dp"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:visibility="gone" android:visibility="gone">
android:background="?attr/selectableItemBackgroundBorderless"
app:tint="?attr/colorOnPrimarySurface" />
<RelativeLayout <ImageButton
android:id="@+id/player_controls" android:id="@+id/unlockBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Unlock player"
android:src="@drawable/ic_lock_open_24dp"
android:background="?attr/selectableItemBackgroundBorderless"
app:tint="?attr/colorOnPrimarySurface" />
</LinearLayout>
<!-- Double layout for consistency in code -->
<LinearLayout
android:id="@+id/controlsView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#70000000"> android:background="#70000000">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/controls_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<ImageButton
android:id="@+id/backArrowBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_arrow_back_24dp"
android:layout_marginHorizontal="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
app:tint="?attr/colorOnPrimarySurface"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/fullTitleTxt"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout
android:id="@+id/fullTitleTxt"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toRightOf="@id/backArrowBtn"
app:layout_constraintRight_toLeftOf="@id/cycleDecoderBtn"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/titleMainTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorOnPrimarySurface"
android:text=""
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/titleSecondaryTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorOnPrimarySurface"
android:alpha = "0.5"
android:textSize="12sp"
android:text="" />
</LinearLayout>
<ImageButton
android:id="@+id/settingsBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:onClick="openSettings"
android:layout_marginRight="10dp"
android:src="@drawable/ic_settings_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:tint="?attr/colorOnPrimarySurface" />
<ImageButton
android:id="@+id/cycleSubsBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:onClick="cycleSub"
android:src="@drawable/ic_subtitles_black_24dp"
android:background="?attr/selectableItemBackgroundBorderless"
app:tint="?attr/colorOnPrimarySurface"
app:layout_constraintRight_toRightOf="@id/cycleAudioBtn"
app:layout_constraintRight_toLeftOf="@id/settingsBtn"
app:layout_constraintTop_toTopOf="parent"/>
<ImageButton
android:id="@+id/cycleAudioBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:onClick="cycleAudio"
android:src="@drawable/ic_audiotrack_black_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="@id/cycleDecoderBtn"
app:layout_constraintRight_toLeftOf="@id/cycleSubsBtn"
app:tint="?attr/colorOnPrimarySurface" />
<Button
android:id="@+id/cycleDecoderBtn"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_toLeftOf="@id/cycleAudioBtn"
android:background="?attr/selectableItemBackgroundBorderless"
android:onClick="switchDecoder"
android:text=".."
android:textColor="?attr/colorOnPrimarySurface"
app:layout_constraintRight_toLeftOf="@id/cycleAudioBtn"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/controls_bottom" android:layout_width="wrap_content"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="match_parent" tools:ignore="UselessParent">
tools:visibility="visible">
<ImageButton <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/play_btn" android:id="@+id/controls_top"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Play/Pause"
android:onClick="playPause"
android:textColor="@android:color/white"
android:visibility="gone"
app:tint="?attr/colorOnPrimarySurface"
tools:src="@drawable/ic_play_arrow_80dp"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/control_bar"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_marginTop="10dp">
android:layout_centerHorizontal="true"
android:orientation="vertical" <ImageButton
tools:visibility="visible"> android:id="@+id/backArrowBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Go back"
android:src="@drawable/ic_arrow_back_24dp"
android:layout_marginHorizontal="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
app:tint="?attr/colorOnPrimarySurface"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/fullTitleTxt"
app:layout_constraintTop_toTopOf="parent"/>
<LinearLayout <LinearLayout
android:id="@+id/controls_title_group" android:id="@+id/fullTitleTxt"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:visibility="visible"> app:layout_constraintLeft_toRightOf="@id/backArrowBtn"
app:layout_constraintRight_toLeftOf="@id/cycleDecoderBtn"
<!-- These two are only used for audio --> app:layout_constraintTop_toTopOf="parent">
<TextView <TextView
android:id="@+id/titleTextView" android:id="@+id/titleMainTxt"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:textColor="?attr/colorOnPrimarySurface"
android:text="-" android:text=""
android:textColor="@color/tint_normal" android:textSize="16sp"
android:textSize="24sp" android:textStyle="bold" />
android:visibility="gone" />
<TextView <TextView
android:id="@+id/minorTitleTextView" android:id="@+id/titleSecondaryTxt"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:textColor="?attr/colorOnPrimarySurface"
android:text="-" android:alpha = "0.5"
android:textColor="@color/tint_normal" android:textSize="12sp"
android:textSize="14sp" android:text="" />
android:visibility="gone" />
</LinearLayout> </LinearLayout>
<ImageButton
android:id="@+id/settingsBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Settings"
android:background="?attr/selectableItemBackground"
android:onClick="openSettings"
android:layout_marginRight="10dp"
android:src="@drawable/ic_settings_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:tint="?attr/colorOnPrimarySurface" />
<ImageButton
android:id="@+id/cycleSubsBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Subtitles"
android:onClick="cycleSub"
android:src="@drawable/ic_subtitles_black_24dp"
android:background="?attr/selectableItemBackground"
app:tint="?attr/colorOnPrimarySurface"
app:layout_constraintRight_toRightOf="@id/cycleAudioBtn"
app:layout_constraintRight_toLeftOf="@id/settingsBtn"
app:layout_constraintTop_toTopOf="parent"/>
<ImageButton
android:id="@+id/cycleAudioBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="Audio"
android:background="?attr/selectableItemBackground"
android:onClick="cycleAudio"
android:src="@drawable/ic_audiotrack_black_24dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="@id/cycleDecoderBtn"
app:layout_constraintRight_toLeftOf="@id/cycleSubsBtn"
app:tint="?attr/colorOnPrimarySurface" />
<Button
android:id="@+id/cycleDecoderBtn"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_toLeftOf="@id/cycleAudioBtn"
android:background="?attr/selectableItemBackground"
android:onClick="switchDecoder"
android:text=".."
android:textColor="?attr/colorOnPrimarySurface"
app:layout_constraintRight_toLeftOf="@id/cycleAudioBtn"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout
android:id="@+id/controls_bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:visibility="visible">
<ImageButton
android:id="@+id/play_btn"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Play/Pause"
android:onClick="playPause"
android:textColor="@android:color/white"
android:visibility="gone"
app:tint="?attr/colorOnPrimarySurface"
tools:src="@drawable/ic_play_arrow_80dp"
tools:visibility="visible" />
<LinearLayout <LinearLayout
android:id="@+id/control_bar"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="vertical"
tools:visibility="visible">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:id="@+id/controls_title_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible">
<!-- These two are only used for audio -->
<TextView
android:id="@+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="-"
android:textColor="@color/tint_normal"
android:textSize="24sp"
android:visibility="gone" />
<TextView
android:id="@+id/minorTitleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="-"
android:textColor="@color/tint_normal"
android:textSize="14sp"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/lockBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="10dp"
android:contentDescription="Lock player"
android:background="?attr/selectableItemBackground"
android:src="@drawable/ic_lock_24dp"
app:tint="?attr/colorOnPrimarySurface" />
<Button
android:id="@+id/cycleSpeedBtn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:onClick="cycleSpeed"
android:text=".."
android:textColor="?attr/colorOnPrimarySurface" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:gravity="right"
android:orientation="horizontal">
<Button
android:id="@+id/controls_skip_intro_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:onClick="skipIntro"
android:text="@string/player_controls_skip_intro_text"
android:textColor="?attr/colorOnPrimarySurface" />
<ImageButton
android:id="@+id/cycleViewModeBtn"
android:layout_width="48dp"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:contentDescription="Cycle view modes"
android:onClick="cycleViewMode"
android:src="@drawable/ic_fullscreen_black_24dp"
app:tint="?attr/colorOnPrimarySurface" />
<ImageButton
android:id="@+id/pipBtn"
android:layout_width="48dp"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/action_player_pip"
android:src="@drawable/ic_picture_in_picture_24dp"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/controls_seekbar_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="100">
<ImageButton <ImageButton
android:id="@+id/lockBtn" android:id="@+id/prevBtn"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_lock_24dp" android:contentDescription="@string/action_previous_episode"
android:padding="@dimen/screen_edge_margin"
app:srcCompat="@drawable/ic_skip_previous_24dp"
app:tint="?attr/colorOnPrimarySurface" /> app:tint="?attr/colorOnPrimarySurface" />
<Button <TextView
android:id="@+id/cycleSpeedBtn" android:id="@+id/playbackPositionTxt"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/selectableItemBackgroundBorderless" android:layout_weight="10"
android:onClick="cycleSpeed" android:gravity="center"
android:text=".." android:text="0:00"
android:textColor="?attr/colorOnPrimarySurface" /> android:textColor="@android:color/white" />
</LinearLayout>
<LinearLayout <SeekBar
android:layout_width="match_parent" android:id="@+id/playbackSeekbar"
android:layout_height="wrap_content" android:layout_width="0dp"
android:layout_marginRight="10dp" android:layout_height="wrap_content"
android:gravity="right" android:layout_gravity="center_vertical"
android:orientation="horizontal"> android:layout_weight="80"
android:progressBackgroundTint="@color/tint_seekbar_bg" />
<Button <TextView
android:id="@+id/controls_skip_intro_btn" android:id="@+id/playbackDurationTxt"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/selectableItemBackgroundBorderless" android:layout_weight="10"
android:onClick="skipIntro" android:gravity="center"
android:text="@string/player_controls_skip_intro_text" android:text="0:00"
android:textColor="?attr/colorOnPrimarySurface" /> android:textColor="@android:color/white" />
<ImageButton <ImageButton
android:id="@+id/cycleViewModeBtn" android:id="@+id/nextBtn"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="match_parent" android:layout_height="48dp"
android:layout_marginRight="10dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Cycle view modes" android:contentDescription="@string/action_next_episode"
android:onClick="cycleViewMode" android:padding="@dimen/screen_edge_margin"
android:src="@drawable/ic_fullscreen_black_24dp" app:srcCompat="@drawable/ic_skip_next_24dp"
app:tint="?attr/colorOnPrimarySurface" /> app:tint="?attr/colorOnPrimarySurface" />
<ImageButton
android:id="@+id/pipBtn"
android:layout_width="48dp"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/action_player_pip"
android:src="@drawable/ic_picture_in_picture_24dp"
android:visibility="visible" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/controls_seekbar_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="100">
<ImageButton
android:id="@+id/prevBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_previous_episode"
android:padding="@dimen/screen_edge_margin"
app:srcCompat="@drawable/ic_skip_previous_24dp"
app:tint="?attr/colorOnPrimarySurface" />
<TextView
android:id="@+id/playbackPositionTxt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10"
android:gravity="center"
android:text="0:00"
android:textColor="@android:color/white" />
<SeekBar
android:id="@+id/playbackSeekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="80"
android:progressBackgroundTint="@color/tint_seekbar_bg" />
<TextView
android:id="@+id/playbackDurationTxt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10"
android:gravity="center"
android:text="0:00"
android:textColor="@android:color/white" />
<ImageButton
android:id="@+id/nextBtn"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginRight="10dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_next_episode"
android:padding="@dimen/screen_edge_margin"
app:srcCompat="@drawable/ic_skip_next_24dp"
app:tint="?attr/colorOnPrimarySurface" />
</LinearLayout>
</LinearLayout>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/volumeView" android:id="@+id/volumeView"
@ -393,7 +413,8 @@
android:layout_height="20dp" android:layout_height="20dp"
android:src="@drawable/ic_volume_high_24dp" android:src="@drawable/ic_volume_high_24dp"
app:tint="?attr/colorOnPrimarySurface" app:tint="?attr/colorOnPrimarySurface"
android:layout_marginTop="5dp"/> android:layout_marginTop="5dp"
tools:ignore="ContentDescription" />
</LinearLayout> </LinearLayout>
@ -432,7 +453,8 @@
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:src="@drawable/ic_brightness_positive_24dp" android:src="@drawable/ic_brightness_positive_24dp"
app:tint="?attr/colorOnPrimarySurface" /> app:tint="?attr/colorOnPrimarySurface"
tools:ignore="ContentDescription" />
</LinearLayout> </LinearLayout>
@ -459,6 +481,21 @@
</LinearLayout> </LinearLayout>
<ImageButton
android:id="@+id/playPauseView"
android:layout_width="80dp"
android:layout_height="80dp"
android:state_enabled="true"
android:state_pressed="true"
android:state_focused="true"
android:layout_centerInParent="true"
android:contentDescription="Play/Pause"
android:textColor="@android:color/white"
android:background="#70000000"
android:visibility="gone"
app:tint="?attr/colorOnPrimarySurface"
tools:src="@drawable/ic_play_arrow_80dp" />
<com.google.android.material.progressindicator.CircularProgressIndicator <com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/loading_indicator" android:id="@+id/loading_indicator"
android:layout_width="100dp" android:layout_width="100dp"