mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-25 22:29:45 +03:00
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:
parent
494b2bb374
commit
c703e1fa86
3 changed files with 394 additions and 323 deletions
|
@ -23,23 +23,9 @@ class Gestures(
|
|||
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 {
|
||||
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 -> activity.toggleControls()
|
||||
e.x > width * 0.6F -> activity.toggleControls()
|
||||
else -> return false
|
||||
}
|
||||
activity.toggleControls()
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -50,20 +36,11 @@ class Gestures(
|
|||
when {
|
||||
e.x < width * 0.4F -> activity.doubleTapSeek(-interval, e)
|
||||
e.x > width * 0.6F -> activity.doubleTapSeek(interval, e)
|
||||
else -> activity.doubleTapPlayPause()
|
||||
}
|
||||
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(
|
||||
e1: MotionEvent,
|
||||
e2: MotionEvent,
|
||||
|
|
|
@ -29,8 +29,8 @@ import android.view.View
|
|||
import android.view.ViewAnimationUtils
|
||||
import android.view.WindowManager
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.SeekBar
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
|
@ -198,9 +198,6 @@ class PlayerActivity :
|
|||
|
||||
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
|
||||
private val seekTextRunnable = Runnable {
|
||||
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
|
||||
private val volumeViewRunnable = Runnable {
|
||||
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
|
||||
private val brightnessViewRunnable = Runnable {
|
||||
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
|
||||
private val controlsViewRunnable = Runnable {
|
||||
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
|
||||
findViewById<RelativeLayout>(R.id.player_controls).startAnimation(fadeAnimation)
|
||||
binding.playerControls.visibility = View.GONE
|
||||
if (!isLocked) {
|
||||
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() {
|
||||
animationHandler.removeCallbacks(controlsViewRunnable)
|
||||
binding.playerControls.visibility = View.VISIBLE
|
||||
private fun showGestureView(type: String) {
|
||||
val callback: Runnable
|
||||
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 {
|
||||
|
@ -311,7 +318,10 @@ class PlayerActivity :
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
window.navigationBarColor = 70000000
|
||||
}
|
||||
|
||||
setVisibilities()
|
||||
showGestureView("controls")
|
||||
|
||||
player.initialize(applicationContext.filesDir.path)
|
||||
MPVLib.setOptionString("keep-open", "always")
|
||||
player.addObserver(this)
|
||||
|
@ -408,19 +418,36 @@ class PlayerActivity :
|
|||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
if (isLocked) {
|
||||
// Hide controls
|
||||
binding.playerControls.isVisible = false
|
||||
binding.controlsView.isVisible = false
|
||||
|
||||
// Toggle unlock button
|
||||
binding.unlockBtn.isVisible = !binding.unlockBtn.isVisible
|
||||
if (!binding.lockedView.isVisible && !player.paused!!) showGestureView("controls")
|
||||
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 {
|
||||
if(!binding.playerControls.isVisible) showControlsView()
|
||||
else { animationHandler.removeCallbacks(controlsViewRunnable); binding.playerControls.isVisible = false }
|
||||
binding.unlockBtn.isVisible = false
|
||||
if (!binding.controlsView.isVisible && !player.paused!!) showGestureView("controls")
|
||||
else if (!binding.controlsView.isVisible && player.paused!!) binding.controlsView.visibility = View.VISIBLE
|
||||
|
||||
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) {
|
||||
binding.playerControls.isVisible = !hide
|
||||
binding.controlsView.isVisible = !hide
|
||||
}
|
||||
|
||||
private fun showLoadingIndicator(visible: Boolean) {
|
||||
|
@ -614,6 +641,37 @@ class PlayerActivity :
|
|||
@Suppress("UNUSED_PARAMETER")
|
||||
fun playPause(view: View) {
|
||||
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) {
|
||||
|
@ -630,7 +688,7 @@ class PlayerActivity :
|
|||
|
||||
val diffText = Utils.prettyTime(time, true)
|
||||
binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText)
|
||||
showSeekText()
|
||||
showGestureView("seek")
|
||||
}
|
||||
|
||||
fun verticalScrollLeft(diff: Float) {
|
||||
|
@ -651,9 +709,8 @@ class PlayerActivity :
|
|||
binding.brightnessText.text = finalBrightness.toString()
|
||||
binding.brightnessBar.progress = finalBrightness
|
||||
binding.brightnessBar.secondaryProgress = abs(finalBrightness)
|
||||
if (finalBrightness >= 0) binding.brightnessImg.setImageResource(R.drawable.ic_brightness_positive_24dp)
|
||||
else binding.brightnessImg.setImageResource(R.drawable.ic_brightness_negative_24dp)
|
||||
showBrightnessView()
|
||||
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 }
|
||||
showGestureView("brightness")
|
||||
}
|
||||
|
||||
fun verticalScrollRight(diff: Float) {
|
||||
|
@ -666,7 +723,7 @@ class PlayerActivity :
|
|||
binding.volumeBar.progress = newVolume
|
||||
if (newVolume == 0) binding.volumeImg.setImageResource(R.drawable.ic_volume_none_24dp)
|
||||
else binding.volumeImg.setImageResource(R.drawable.ic_volume_high_24dp)
|
||||
showVolumeView()
|
||||
showGestureView("volume")
|
||||
}
|
||||
|
||||
fun initSeek() {
|
||||
|
@ -687,7 +744,7 @@ class PlayerActivity :
|
|||
|
||||
val diffText = Utils.prettyTime(newDiff, true)
|
||||
binding.seekText.text = getString(R.string.ui_seek_distance, Utils.prettyTime(newPos), diffText)
|
||||
showSeekText()
|
||||
showGestureView("seek")
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
|
|
|
@ -48,24 +48,38 @@
|
|||
app:tint="?attr/colorAccent" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/lockedView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/unlockBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:contentDescription="Unlock player"
|
||||
android:src="@drawable/ic_lock_open_24dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:visibility="gone"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/player_controls"
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Double layout for consistency in code -->
|
||||
<LinearLayout
|
||||
android:id="@+id/controlsView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#70000000">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/controls_top"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -76,6 +90,7 @@
|
|||
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"
|
||||
|
@ -119,7 +134,8 @@
|
|||
android:id="@+id/settingsBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="Settings"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:onClick="openSettings"
|
||||
android:layout_marginRight="10dp"
|
||||
android:src="@drawable/ic_settings_24dp"
|
||||
|
@ -132,9 +148,10 @@
|
|||
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/selectableItemBackgroundBorderless"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
app:tint="?attr/colorOnPrimarySurface"
|
||||
app:layout_constraintRight_toRightOf="@id/cycleAudioBtn"
|
||||
app:layout_constraintRight_toLeftOf="@id/settingsBtn"
|
||||
|
@ -144,7 +161,8 @@
|
|||
android:id="@+id/cycleAudioBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="Audio"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:onClick="cycleAudio"
|
||||
android:src="@drawable/ic_audiotrack_black_24dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
@ -157,7 +175,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_toLeftOf="@id/cycleAudioBtn"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:onClick="switchDecoder"
|
||||
android:text=".."
|
||||
android:textColor="?attr/colorOnPrimarySurface"
|
||||
|
@ -243,7 +261,8 @@
|
|||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="Lock player"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:src="@drawable/ic_lock_24dp"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
|
||||
|
@ -251,7 +270,7 @@
|
|||
android:id="@+id/cycleSpeedBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:onClick="cycleSpeed"
|
||||
android:text=".."
|
||||
android:textColor="?attr/colorOnPrimarySurface" />
|
||||
|
@ -268,7 +287,7 @@
|
|||
android:id="@+id/controls_skip_intro_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:onClick="skipIntro"
|
||||
android:text="@string/player_controls_skip_intro_text"
|
||||
android:textColor="?attr/colorOnPrimarySurface" />
|
||||
|
@ -277,7 +296,7 @@
|
|||
android:id="@+id/cycleViewModeBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="Cycle view modes"
|
||||
android:onClick="cycleViewMode"
|
||||
android:src="@drawable/ic_fullscreen_black_24dp"
|
||||
|
@ -356,6 +375,7 @@
|
|||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volumeView"
|
||||
|
@ -393,7 +413,8 @@
|
|||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_volume_high_24dp"
|
||||
app:tint="?attr/colorOnPrimarySurface"
|
||||
android:layout_marginTop="5dp"/>
|
||||
android:layout_marginTop="5dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -432,7 +453,8 @@
|
|||
android:layout_height="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:src="@drawable/ic_brightness_positive_24dp"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
app:tint="?attr/colorOnPrimarySurface"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -459,6 +481,21 @@
|
|||
|
||||
</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
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="100dp"
|
||||
|
|
Loading…
Reference in a new issue