Merge pull request #882 from Bnyro/master

refactor double tap in the player to allow other gestures
This commit is contained in:
Bnyro 2022-07-27 09:00:57 +02:00 committed by GitHub
commit e61c460ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 100 additions and 60 deletions

View File

@ -20,10 +20,7 @@ import android.support.v4.media.session.MediaSessionCompat
import android.text.Html
import android.text.TextUtils
import android.util.Log
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
@ -63,6 +60,7 @@ import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.ConnectionHelper
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter
import com.github.libretube.util.OnCustomEventListener
import com.github.libretube.util.PlayerHelper
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort
@ -1096,50 +1094,17 @@ class PlayerFragment : Fragment() {
val seekIncrementText = (seekIncrement / 1000).toString()
doubleTapOverlayBinding.rewindTV.text = seekIncrementText
doubleTapOverlayBinding.forwardTV.text = seekIncrementText
// enable rewind button
val rewindGestureDetector = GestureDetector(
context,
object : SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent): Boolean {
rewind()
return super.onDoubleTap(e)
}
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
toggleController()
return super.onSingleTapConfirmed(e)
binding.player.setOnDoubleTapListener(
object : OnCustomEventListener {
override fun onEvent(x: Float) {
val width = exoPlayerView.width
when {
width * 0.45 > x -> rewind()
width * 0.55 < x -> forward()
}
}
}
)
doubleTapOverlayBinding.rewindFL.setOnTouchListener { view, event ->
rewindGestureDetector.onTouchEvent(event)
view.performClick()
true
}
// enable forward button
val forwardGestureDetector = GestureDetector(
context,
object : SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent): Boolean {
forward()
return super.onDoubleTap(e)
}
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
toggleController()
return super.onSingleTapConfirmed(e)
}
}
)
doubleTapOverlayBinding.forwardFL.setOnTouchListener { view, event ->
forwardGestureDetector.onTouchEvent(event)
view.performClick()
true
}
}
private fun rewind() {
@ -1555,10 +1520,10 @@ class PlayerFragment : Fragment() {
// disable double tap to seek when the player is locked
if (isLocked) {
// enable fast forward and rewind by double tapping
binding.doubleTapOverlay.visibility = View.VISIBLE
enableDoubleTapToSeek()
} else {
// disable fast forward and rewind by double tapping
binding.doubleTapOverlay.visibility = View.GONE
binding.player.setOnDoubleTapListener(null)
}
}

View File

@ -0,0 +1,45 @@
package com.github.libretube.util
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.view.View
abstract class DoubleTapListener : View.OnClickListener {
private var isSingleEvent = false
private val doubleClickQualificationSpanInMillis: Long
private var timestampLastClick: Long
private val handler: Handler
private val runnable: Runnable
override fun onClick(v: View?) {
if (SystemClock.elapsedRealtime() - timestampLastClick < doubleClickQualificationSpanInMillis) {
isSingleEvent = false
handler.removeCallbacks(runnable)
onDoubleClick()
return
}
isSingleEvent = true
handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN)
timestampLastClick = SystemClock.elapsedRealtime()
}
abstract fun onDoubleClick()
abstract fun onSingleClick()
companion object {
private const val DEFAULT_QUALIFICATION_SPAN: Long = 200
}
init {
doubleClickQualificationSpanInMillis = DEFAULT_QUALIFICATION_SPAN
timestampLastClick = 0
handler = Handler(Looper.getMainLooper())
runnable = Runnable {
if (isSingleEvent) {
onSingleClick()
}
}
}
}

View File

@ -0,0 +1,5 @@
package com.github.libretube.util
interface OnCustomEventListener {
fun onEvent(x: Float)
}

View File

@ -7,8 +7,11 @@ import android.view.MotionEvent
import android.view.View
import com.github.libretube.R
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.util.DoubleTapListener
import com.github.libretube.util.OnCustomEventListener
import com.google.android.exoplayer2.ui.StyledPlayerView
@SuppressLint("ClickableViewAccessibility")
internal class CustomExoPlayerView(
context: Context,
attributeSet: AttributeSet? = null
@ -16,12 +19,39 @@ internal class CustomExoPlayerView(
val TAG = "CustomExoPlayerView"
val binding: ExoStyledPlayerControlViewBinding = ExoStyledPlayerControlViewBinding.bind(this)
var doubleTapListener: OnCustomEventListener? = null
var lastToggled: Long? = null
var xPos = 0F
fun setOnDoubleTapListener(
eventListener: OnCustomEventListener?
) {
doubleTapListener = eventListener
}
private fun toggleController() {
lastToggled = System.currentTimeMillis()
if (isControllerFullyVisible) hideController() else showController()
}
val doubleTouchListener = object : DoubleTapListener() {
override fun onDoubleClick() {
doubleTapListener?.onEvent(xPos)
}
override fun onSingleClick() {
toggleController()
}
}
init {
setControllerVisibilityListener {
// hide the advanced options
binding.toggleOptions.animate().rotation(0F).setDuration(250).start()
binding.advancedOptions.visibility = View.GONE
}
setOnClickListener(doubleTouchListener)
}
override fun hideController() {
@ -44,17 +74,9 @@ internal class CustomExoPlayerView(
doubleTapOverlay.layoutParams = params
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
if (isControllerFullyVisible) {
hideController()
} else {
showController()
}
}
}
xPos = event.x
doubleTouchListener.onClick(this)
return false
}
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -11,7 +10,9 @@
android:id="@+id/rewindFL"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".40">
android:layout_weight=".40"
android:clickable="false"
android:focusable="false">
<FrameLayout
android:id="@+id/rewindBTN"
@ -51,7 +52,9 @@
android:id="@+id/forwardFL"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".40">
android:layout_weight=".40"
android:clickable="false"
android:focusable="false">
<FrameLayout
android:id="@+id/forwardBTN"