Fix gesture controls for portrait videos

Use `PlayerViewModel.isFullscreen` to check if video is playing in full screen instead of screen orientation.
Scale progress bar `progress` according to it's max size.
This commit is contained in:
Krunal Patel 2022-11-28 11:54:31 +05:30
parent b3824b2e43
commit fe02b0e30c
6 changed files with 61 additions and 25 deletions

View File

@ -9,6 +9,7 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import androidx.activity.viewModels
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
@ -16,6 +17,7 @@ import com.github.libretube.constants.IntentData
import com.github.libretube.databinding.ActivityOfflinePlayerBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.ui.models.PlayerViewModel
import com.github.libretube.util.DownloadHelper
import com.github.libretube.util.PlayerHelper
import com.google.android.exoplayer2.ExoPlayer
@ -32,6 +34,7 @@ class OfflinePlayerActivity : BaseActivity() {
private lateinit var player: ExoPlayer
private lateinit var playerView: StyledPlayerView
private lateinit var playerBinding: ExoStyledPlayerControlViewBinding
private val playerViewModel: PlayerViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
hideSystemBars()
@ -154,6 +157,16 @@ class OfflinePlayerActivity : BaseActivity() {
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}
override fun onResume() {
playerViewModel.isFullscreen.value = true
super.onResume()
}
override fun onPause() {
playerViewModel.isFullscreen.value = false
super.onPause()
}
override fun onDestroy() {
player.release()
super.onDestroy()

View File

@ -19,4 +19,6 @@ interface PlayerGestureOptions {
fun onZoom()
fun onMinimize()
fun onFullscreenChange(isFullscreen: Boolean)
}

View File

@ -85,11 +85,11 @@ internal class CustomExoPlayerView(
this.doubleTapOverlayBinding = doubleTapOverlayBinding
this.trackSelector = trackSelector
this.gestureViewBinding = playerGestureControlsViewBinding
this.playerGestureController = PlayerGestureController(context, this)
this.playerGestureController = PlayerGestureController(context as BaseActivity, this)
this.brightnessHelper = BrightnessHelper(context as Activity)
this.audioHelper = AudioHelper(context)
// Set touch listner for tap and swipe gestures.
// Set touch listener for tap and swipe gestures.
setOnTouchListener(playerGestureController)
initializeGestureProgress()
@ -461,13 +461,6 @@ internal class CustomExoPlayerView(
params.bottomMargin = offset.toInt()
it.layoutParams = params
}
if (PlayerHelper.swipeGestureEnabled && this::brightnessHelper.isInitialized) {
when (newConfig?.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> brightnessHelper.restoreSavedBrightness()
else -> brightnessHelper.resetToSystemBrightness(false)
}
}
}
override fun onSingleTap() {
@ -497,14 +490,14 @@ internal class CustomExoPlayerView(
}
override fun onSwipeLeftScreen(distanceY: Float) {
if (!PlayerHelper.swipeGestureEnabled || resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) return
if (!PlayerHelper.swipeGestureEnabled) return
if (isControllerFullyVisible) hideController()
updateBrightness(distanceY)
}
override fun onSwipeRightScreen(distanceY: Float) {
if (!PlayerHelper.swipeGestureEnabled || resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) return
if (!PlayerHelper.swipeGestureEnabled) return
if (isControllerFullyVisible) hideController()
updateVolume(distanceY)
@ -522,4 +515,14 @@ internal class CustomExoPlayerView(
override fun onMinimize() {
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
}
override fun onFullscreenChange(isFullscreen: Boolean) {
if (PlayerHelper.swipeGestureEnabled && this::brightnessHelper.isInitialized) {
if (isFullscreen) {
brightnessHelper.restoreSavedBrightness()
} else {
brightnessHelper.resetToSystemBrightness(false)
}
}
}
}

View File

@ -5,6 +5,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import com.github.libretube.databinding.PlayerGestureControlsViewBinding
import com.github.libretube.extensions.normalize
class PlayerGestureControlsView(
context: Context,
@ -20,7 +21,21 @@ class PlayerGestureControlsView(
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
super.onSizeChanged(width, height, oldHeight, oldHeight)
binding.brightnessProgressBar.max = (height * 0.7).toInt()
binding.volumeProgressBar.max = (height * 0.7).toInt()
// Set new max value of progress bar corresponding to the new height and
// make progress accordingly, store oldProgress before changing it to avoid
// inconsistency when old progress > new max
binding.brightnessProgressBar.apply {
val oldMax = max
val oldProgress = progress
max = (height * 0.7).toInt()
progress = oldProgress.normalize(0, oldMax, 0, max)
}
binding.volumeProgressBar.apply {
val oldMax = max
val oldProgress = progress
max = (height * 0.7).toInt()
progress = oldProgress.normalize(0, oldMax, 0, max)
}
}
}

View File

@ -1,7 +1,6 @@
package com.github.libretube.util
import android.app.Activity
import android.os.Build
import android.view.WindowManager
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.extensions.normalize
@ -46,9 +45,6 @@ class BrightnessHelper(private val activity: Activity) {
* Set current screen brightness to saved brightness value.
*/
fun restoreSavedBrightness() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && activity.isInPictureInPictureMode) {
return
}
brightness = savedBrightness
}

View File

@ -1,8 +1,6 @@
package com.github.libretube.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Handler
import android.os.Looper
@ -11,27 +9,36 @@ import android.view.GestureDetector
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import androidx.activity.viewModels
import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.ui.interfaces.PlayerGestureOptions
import com.github.libretube.ui.models.PlayerViewModel
import kotlin.math.abs
class PlayerGestureController(context: Context, private val listener: PlayerGestureOptions) :
class PlayerGestureController(activity: BaseActivity, private val listener: PlayerGestureOptions) :
View.OnTouchListener {
// width and height should be obtained each time using getter to adopt layout size changes.
private val width get() = Resources.getSystem().displayMetrics.widthPixels
private val height get() = Resources.getSystem().displayMetrics.heightPixels
private val orientation get() = Resources.getSystem().configuration.orientation
private val elapsedTime get() = SystemClock.elapsedRealtime()
private val playerViewModel: PlayerViewModel by activity.viewModels()
private val handler: Handler = Handler(Looper.getMainLooper())
private val gestureDetector: GestureDetector
private val scaleGestureDetector: ScaleGestureDetector
private var isFullscreen = false
private var isMoving = false
var isEnabled = true
init {
gestureDetector = GestureDetector(context, GestureListener(), handler)
scaleGestureDetector = ScaleGestureDetector(context, ScaleGestureListener(), handler)
gestureDetector = GestureDetector(activity, GestureListener(), handler)
scaleGestureDetector = ScaleGestureDetector(activity, ScaleGestureListener(), handler)
playerViewModel.isFullscreen.observe(activity) {
isFullscreen = it
listener.onFullscreenChange(it)
}
}
@SuppressLint("ClickableViewAccessibility")
@ -47,8 +54,8 @@ class PlayerGestureController(context: Context, private val listener: PlayerGest
gestureDetector.onTouchEvent(event)
} catch (_: Exception) { }
// If orientation is landscape then allow `onScroll` to consume event and return true.
return orientation == Configuration.ORIENTATION_LANDSCAPE
// If video is playing in full-screen then allow `onScroll` to consume event and return true.
return isFullscreen
}
private inner class ScaleGestureListener : ScaleGestureDetector.OnScaleGestureListener {