From 27777bf352a16483c183fb9c81e8e14d23a3a66f Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Tue, 17 Nov 2020 08:47:45 -0700 Subject: [PATCH] Add animation to BottomNavigationView nav Add an animation to the navigation that occurs when an item from BottomNavigationView is selected. --- .../java/org/oxycblt/auxio/MainFragment.kt | 59 +++++++++++++++---- .../auxio/playback/PlaybackViewModel.kt | 14 ----- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index c57bcefcd..c79b50429 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -4,14 +4,18 @@ import android.content.res.ColorStateList import android.os.Bundle import android.util.Log import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.navigation.NavController +import androidx.navigation.NavOptions import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController -import androidx.navigation.ui.setupWithNavController +import androidx.navigation.ui.NavigationUI import org.oxycblt.auxio.databinding.FragmentMainBinding import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.playback.PlaybackViewModel @@ -19,16 +23,11 @@ import org.oxycblt.auxio.ui.accent import org.oxycblt.auxio.ui.getInactiveAlpha import org.oxycblt.auxio.ui.getTransparentAccent import org.oxycblt.auxio.ui.toColor +import java.lang.IllegalArgumentException class MainFragment : Fragment() { private val playbackModel: PlaybackViewModel by activityViewModels() - private val shownFragments = listOf(0, 1) - private val tabIcons = listOf( - R.drawable.ic_library, - R.drawable.ic_song - ) - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -50,6 +49,8 @@ class MainFragment : Fragment() { accent.first, getInactiveAlpha(accent.first) ) + + // Set up the tints for the navigation icon val navIconTints = ColorStateList( arrayOf( intArrayOf(-android.R.attr.state_checked), @@ -58,15 +59,22 @@ class MainFragment : Fragment() { intArrayOf(colorInactive, colorActive) ) + val navController = ( + childFragmentManager.findFragmentById(R.id.explore_nav_host) + as NavHostFragment? + )?.findNavController() + // --- UI SETUP --- binding.lifecycleOwner = this binding.navBar.itemIconTintList = navIconTints binding.navBar.itemTextColor = navIconTints - ((childFragmentManager.findFragmentById(R.id.explore_nav_host) as NavHostFragment?))?.let { - // TODO: Add animation with BottomNavigationView navs - binding.navBar.setupWithNavController(it.findNavController()) + + navController?.let { + binding.navBar.setOnNavigationItemSelectedListener { item -> + navigateWithItem(item, navController) + } } // --- VIEWMODEL SETUP --- @@ -89,4 +97,35 @@ class MainFragment : Fragment() { return binding.root } + + /** + * Some custom navigator code based off [NavigationUI] that makes animations function + */ + private fun navigateWithItem(item: MenuItem, navController: NavController): Boolean { + // Custom navigator code so that animations actually function + // [Which doesn't happen if I use BottomNavigationView.setupWithNavController() + if (item.itemId != navController.currentDestination!!.id) { + val builder = NavOptions.Builder().setLaunchSingleTop(true) + + builder.setEnterAnim(R.anim.nav_default_enter_anim) + .setExitAnim(R.anim.nav_default_exit_anim) + .setPopEnterAnim(R.anim.nav_default_enter_anim) + .setPopExitAnim(R.anim.nav_default_exit_anim) + + if ((item.order and Menu.CATEGORY_SECONDARY) == 0) { + builder.setPopUpTo(navController.graph.startDestination, false) + } + + val options = builder.build() + + return try { + navController.navigate(item.itemId, null, options) + true + } catch (e: IllegalArgumentException) { + false + } + } + + return true + } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index b00f29393..087e819de 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.ViewModel -import org.oxycblt.auxio.database.QueueConverter import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.BaseModel @@ -160,19 +159,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { playbackManager.prev() } - fun goto(value: Boolean) { - Log.d( - this::class.simpleName, - QueueConverter.fromQueue( - mutableListOf().apply { - forEach { - this.add(it) - } - } - ) - ) - } - // Remove a queue OR user queue item, given a QueueAdapter index. fun removeQueueItem(adapterIndex: Int, queueAdapter: QueueAdapter) { var index = adapterIndex.dec()