[BottomNavigation] Better animations for BottomNavigationView

This commit is contained in:
Prathamesh More 2021-12-02 23:56:07 +05:30
parent e02e99ed02
commit 91a4282581
5 changed files with 27 additions and 38 deletions

View file

@ -110,7 +110,7 @@ dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
def room_version = '2.4.0-beta02'
def room_version = '2.4.0-rc01'
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"

View file

@ -134,8 +134,6 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener {
PreferenceUtil.registerOnSharedPreferenceChangedListener(this)
val expand = extra<Boolean>(EXPAND_PANEL).value ?: false
if (expand && PreferenceUtil.isExpandPanel) {
setBottomNavVisibility(false)
fromNotification = true
expandPanel()
intent.removeExtra(EXPAND_PANEL)
}

View file

@ -14,7 +14,6 @@
*/
package code.name.monkey.retromusic.activities.base
import android.animation.Animator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
@ -67,11 +66,9 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
companion object {
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
var fromNotification: Boolean = false
}
private var windowInsets: WindowInsetsCompat? = null
private var bottomNavAnimator: Animator? = null
protected val libraryViewModel by viewModel<LibraryViewModel>()
private lateinit var bottomSheetBehavior: RetroBottomSheetBehavior<FrameLayout>
private var playerFragment: AbsPlayerFragment? = null
@ -96,15 +93,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
}
STATE_COLLAPSED -> {
onPanelCollapsed()
if (fromNotification) {
hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty())
fromNotification = false
}
}
STATE_SETTLING, STATE_DRAGGING -> {
if (fromNotification) {
bottomNavigationView.isVisible = true
}
}
else -> {
println("Do something")
@ -319,53 +307,55 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
}
fun setBottomNavVisibility(visible: Boolean, animate: Boolean = false) {
binding.bottomNavigationView.isVisible = visible
hideBottomSheet(MusicPlayerRemote.playingQueue.isEmpty(), animate)
binding.bottomNavigationView.translateYAnimate(if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets())
.apply {
doOnEnd {
binding.bottomNavigationView.bringToFront()
}
hideBottomSheet(
hide = MusicPlayerRemote.playingQueue.isEmpty(),
animate = animate,
isBottomNavVisible = visible
)
}
}
fun hideBottomSheet(hide: Boolean, animate: Boolean = false) {
fun hideBottomSheet(
hide: Boolean,
animate: Boolean = false,
isBottomNavVisible: Boolean = bottomNavigationView.isVisible
) {
val heightOfBar =
windowInsets.safeGetBottomInsets() +
if (MusicPlayerRemote.isCasting) dip(R.dimen.cast_mini_player_height) else dip(R.dimen.mini_player_height)
val heightOfBarWithTabs = heightOfBar + dip(R.dimen.bottom_nav_height)
val isVisible = binding.bottomNavigationView.isVisible
if (hide) {
bottomSheetBehavior.peekHeight = -windowInsets.safeGetBottomInsets()
bottomSheetBehavior.state = STATE_COLLAPSED
libraryViewModel.setFabMargin(if (isVisible) dip(R.dimen.bottom_nav_height) else 0)
libraryViewModel.setFabMargin(if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0)
ViewCompat.setElevation(binding.slidingPanel, 0f)
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
} else {
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
ViewCompat.setElevation(binding.slidingPanel, 10f)
ViewCompat.setElevation(binding.bottomNavigationView, 10f)
if (isVisible) {
if (isBottomNavVisible) {
println("List")
if (animate) {
bottomNavAnimator?.end()
bottomSheetBehavior.peekHeightAnimate(heightOfBarWithTabs)
bottomNavAnimator = binding.bottomNavigationView.translateYAnimate(0F)
} else {
bottomSheetBehavior.peekHeight = heightOfBarWithTabs
binding.bottomNavigationView.translationY = 0F
}
binding.bottomNavigationView.bringToFront()
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height_expanded))
} else {
println("Details")
if (animate) {
bottomSheetBehavior.peekHeightAnimate(heightOfBar)
bottomNavAnimator?.end()
bottomNavAnimator =
bottomNavigationView.translateYAnimate(dip(R.dimen.bottom_nav_height).toFloat())
bottomNavAnimator?.doOnEnd {
bottomSheetBehavior.peekHeightAnimate(heightOfBar).doOnEnd {
binding.slidingPanel.bringToFront()
}
} else {
bottomSheetBehavior.peekHeight = heightOfBar
binding.bottomNavigationView.translationY =
dip(R.dimen.bottom_nav_height).toFloat()
binding.slidingPanel.bringToFront()
}
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height))

View file

@ -37,6 +37,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.imageview.ShapeableImageView
import com.google.android.material.shape.ShapeAppearanceModel
@Suppress("UNCHECKED_CAST")
fun <T : View> ViewGroup.inflate(@LayoutRes layout: Int): T {
return LayoutInflater.from(context).inflate(layout, this, false) as T
@ -67,21 +68,21 @@ fun View.translateYAnimate(value: Float): Animator {
.apply {
duration = 300
doOnStart {
if (value == 0f) {
show()
}
}
doOnEnd {
if (value != 0f) {
hide()
} else {
show()
}
}
start()
}
}
fun BottomSheetBehavior<*>.peekHeightAnimate(value: Int) {
ObjectAnimator.ofInt(this, "peekHeight", value)
fun BottomSheetBehavior<*>.peekHeightAnimate(value: Int): Animator {
return ObjectAnimator.ofInt(this, "peekHeight", value)
.apply {
duration = 300
start()

View file

@ -11,7 +11,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
def nav_version = "2.4.0-beta02"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.0"
classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.1"
}
}