[Android] Improve miniplayer / bottombar behavior compatibility
Nicolas Pomepuy
git at videolan.org
Thu Apr 16 15:43:37 CEST 2020
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Apr 8 09:14:47 2020 +0200| [52d2c01b909bd2ef523e7a4a8e5ab548693a4444] | committer: Nicolas Pomepuy
Improve miniplayer / bottombar behavior compatibility
> https://code.videolan.org/videolan/vlc-android/commit/52d2c01b909bd2ef523e7a4a8e5ab548693a4444
---
.../vlc/gui/AudioPlayerContainerActivity.kt | 37 ++++++++++++++++++++--
.../vlc/gui/helpers/BottomNavigationBehavior.kt | 17 ++++++++--
.../src/org/videolan/vlc/gui/helpers/UiTools.kt | 9 ++++++
3 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
index cc8163d8c..8ce447642 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
@@ -58,8 +58,10 @@ import org.videolan.tools.*
import org.videolan.vlc.*
import org.videolan.vlc.gui.audio.AudioPlayer
import org.videolan.vlc.gui.browser.StorageBrowserFragment
+import org.videolan.vlc.gui.helpers.BottomNavigationBehavior
import org.videolan.vlc.gui.helpers.PlayerBehavior
import org.videolan.vlc.gui.helpers.UiTools
+import org.videolan.vlc.gui.helpers.getHeightWhenReady
import org.videolan.vlc.interfaces.IRefreshable
import org.videolan.vlc.media.PlaylistManager
@@ -68,7 +70,7 @@ private const val TAG = "VLC/APCActivity"
private const val ACTION_DISPLAY_PROGRESSBAR = 1339
private const val ACTION_SHOW_PLAYER = 1340
private const val ACTION_HIDE_PLAYER = 1341
-
+private const val BOTTOM_IS_HIDDEN = "bottom_is_hidden"
@SuppressLint("Registered")
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
@@ -105,11 +107,14 @@ open class AudioPlayerContainerActivity : BaseActivity() {
val isAudioPlayerExpanded: Boolean
get() = isAudioPlayerReady && playerBehavior.state == STATE_EXPANDED
+ var bottomIsHiddden: Boolean = false
+
override fun onCreate(savedInstanceState: Bundle?) {
//Init Medialibrary if KO
if (savedInstanceState != null) {
this.startMedialibrary(firstRun = false, upgrade = false, parse = true)
+ bottomIsHiddden = savedInstanceState.getBoolean(BOTTOM_IS_HIDDEN, false)
}
super.onCreate(savedInstanceState)
volumeControlStream = AudioManager.STREAM_MUSIC
@@ -127,6 +132,13 @@ open class AudioPlayerContainerActivity : BaseActivity() {
tabLayout = findViewById(R.id.sliding_tabs)
appBarLayout.setExpanded(true)
bottomBar = findViewById(R.id.navigation)
+ if (bottomIsHiddden) {
+ bottomBar?.let {
+ val bottomBehavior = BottomNavigationBehavior.from(it) as BottomNavigationBehavior<*>
+ bottomBehavior.isPlayerHidden = true
+ it.getHeightWhenReady { height -> it.translationY = height.toFloat() }
+ }
+ }
tabLayout?.viewTreeObserver?.addOnGlobalLayoutListener {
//add a shadow if there are tabs
if (AndroidUtil.isLolliPopOrLater) appBarLayout.elevation = if (tabLayout?.isVisible() == true) 4.dp.toFloat() else 0.dp.toFloat()
@@ -142,6 +154,8 @@ open class AudioPlayerContainerActivity : BaseActivity() {
findViewById<View>(R.id.audio_player_stub).visibility = View.VISIBLE
audioPlayer = supportFragmentManager.findFragmentById(R.id.audio_player) as AudioPlayer
playerBehavior = from(audioPlayerContainer) as PlayerBehavior<*>
+ val bottomBehavior = bottomBar?.let { BottomNavigationBehavior.from(it) as BottomNavigationBehavior<*> }
+ ?: null
playerBehavior.peekHeight = resources.getDimensionPixelSize(R.dimen.player_peek_height)
playerBehavior.addBottomSheetCallback(object : BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
@@ -152,13 +166,30 @@ open class AudioPlayerContainerActivity : BaseActivity() {
onPlayerStateChanged(bottomSheet, newState)
audioPlayer.onStateChanged(newState)
if (newState == STATE_COLLAPSED || newState == STATE_HIDDEN) removeTipViewIfDisplayed()
- if (newState == STATE_DRAGGING) bottomBar?.animate()?.translationY(bottomBar?.height?.toFloat()
- ?: 0F)
+ bottomBehavior?.let { bottomBehavior ->
+ bottomBar?.let { bottomBar ->
+ if (newState == STATE_DRAGGING) {
+ bottomBehavior.animateBarVisibility(bottomBar, false)
+ bottomBehavior.isPlayerHidden = true
+ }
+ if (newState == STATE_COLLAPSED) {
+ bottomBehavior.animateBarVisibility(bottomBar, true)
+ bottomBehavior.isPlayerHidden = false
+ }
+ }
+ }
+
}
})
showTipViewIfNeeded(R.id.audio_player_tips, PREF_AUDIOPLAYER_TIPS_SHOWN)
}
+ override fun onSaveInstanceState(outState: Bundle) {
+ outState.putBoolean(BOTTOM_IS_HIDDEN, bottomBar?.let { BottomNavigationBehavior.from(it) as BottomNavigationBehavior<*> }?.isPlayerHidden
+ ?: false)
+ super.onSaveInstanceState(outState)
+ }
+
fun expandAppBar() {
appBarLayout.setExpanded(true)
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/BottomNavigationBehavior.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/BottomNavigationBehavior.kt
index 8ba765814..761faac73 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/BottomNavigationBehavior.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/BottomNavigationBehavior.kt
@@ -46,6 +46,7 @@ class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet)
private var lastStartedType: Int = 0
private var offsetAnimator: ValueAnimator? = null
private var isSnappingEnabled = true
+ var isPlayerHidden = false
private var player: FrameLayout? = null
override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
@@ -69,6 +70,7 @@ class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet)
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout, child: V, directTargetChild: View, target: View, axes: Int, type: Int
): Boolean {
+ if (isPlayerHidden) return false
if (axes != ViewCompat.SCROLL_AXIS_VERTICAL)
return false
@@ -123,7 +125,9 @@ class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet)
}
}
- private fun animateBarVisibility(child: View, isVisible: Boolean) {
+ fun animateBarVisibility(child: View, isVisible: Boolean) {
+ val targetTranslation = if (isVisible) 0f else child.height.toFloat()
+ if (child.translationY == targetTranslation) return
if (offsetAnimator == null) {
offsetAnimator = ValueAnimator().apply {
interpolator = DecelerateInterpolator()
@@ -139,8 +143,17 @@ class BottomNavigationBehavior<V : View>(context: Context, attrs: AttributeSet)
offsetAnimator?.cancel()
}
- val targetTranslation = if (isVisible) 0f else child.height.toFloat()
offsetAnimator?.setFloatValues(child.translationY, targetTranslation)
offsetAnimator?.start()
}
+
+ companion object {
+ fun <V : View> from(view: V): BottomNavigationBehavior<V>? {
+ val params = view.layoutParams
+ require(params is CoordinatorLayout.LayoutParams) { "The view is not a child of CoordinatorLayout" }
+ val behavior = params.behavior
+ require(behavior is BottomNavigationBehavior<*>) { "The view is not associated with BottomNavigationBehavior" }
+ return behavior as BottomNavigationBehavior<V>?
+ }
+ }
}
\ No newline at end of file
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
index e4b9e88a3..37b06a7b1 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
@@ -671,3 +671,12 @@ fun getTvIconRes(mediaLibraryItem: MediaLibraryItem) = when (mediaLibraryItem.it
}
else -> R.drawable.ic_browser_unknown_big_normal
}
+
+fun View.getHeightWhenReady(listener: (height: Int) -> Unit) {
+ viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ listener(height)
+ viewTreeObserver.removeOnGlobalLayoutListener(this)
+ }
+ })
+}
More information about the Android
mailing list