Add animation to BottomNavigationView nav
Add an animation to the navigation that occurs when an item from BottomNavigationView is selected.
This commit is contained in:
parent
c19680c1f7
commit
27777bf352
2 changed files with 49 additions and 24 deletions
|
@ -4,14 +4,18 @@ import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
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.databinding.FragmentMainBinding
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
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.getInactiveAlpha
|
||||||
import org.oxycblt.auxio.ui.getTransparentAccent
|
import org.oxycblt.auxio.ui.getTransparentAccent
|
||||||
import org.oxycblt.auxio.ui.toColor
|
import org.oxycblt.auxio.ui.toColor
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
class MainFragment : Fragment() {
|
class MainFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
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(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -50,6 +49,8 @@ class MainFragment : Fragment() {
|
||||||
accent.first,
|
accent.first,
|
||||||
getInactiveAlpha(accent.first)
|
getInactiveAlpha(accent.first)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Set up the tints for the navigation icon
|
||||||
val navIconTints = ColorStateList(
|
val navIconTints = ColorStateList(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
intArrayOf(-android.R.attr.state_checked),
|
intArrayOf(-android.R.attr.state_checked),
|
||||||
|
@ -58,15 +59,22 @@ class MainFragment : Fragment() {
|
||||||
intArrayOf(colorInactive, colorActive)
|
intArrayOf(colorInactive, colorActive)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val navController = (
|
||||||
|
childFragmentManager.findFragmentById(R.id.explore_nav_host)
|
||||||
|
as NavHostFragment?
|
||||||
|
)?.findNavController()
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
|
|
||||||
binding.navBar.itemIconTintList = navIconTints
|
binding.navBar.itemIconTintList = navIconTints
|
||||||
binding.navBar.itemTextColor = navIconTints
|
binding.navBar.itemTextColor = navIconTints
|
||||||
((childFragmentManager.findFragmentById(R.id.explore_nav_host) as NavHostFragment?))?.let {
|
|
||||||
// TODO: Add animation with BottomNavigationView navs
|
navController?.let {
|
||||||
binding.navBar.setupWithNavController(it.findNavController())
|
binding.navBar.setOnNavigationItemSelectedListener { item ->
|
||||||
|
navigateWithItem(item, navController)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
@ -89,4 +97,35 @@ class MainFragment : Fragment() {
|
||||||
|
|
||||||
return binding.root
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import org.oxycblt.auxio.database.QueueConverter
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
@ -160,19 +159,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
playbackManager.prev()
|
playbackManager.prev()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun goto(value: Boolean) {
|
|
||||||
Log.d(
|
|
||||||
this::class.simpleName,
|
|
||||||
QueueConverter.fromQueue(
|
|
||||||
mutableListOf<Long>().apply {
|
|
||||||
forEach {
|
|
||||||
this.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a queue OR user queue item, given a QueueAdapter index.
|
// Remove a queue OR user queue item, given a QueueAdapter index.
|
||||||
fun removeQueueItem(adapterIndex: Int, queueAdapter: QueueAdapter) {
|
fun removeQueueItem(adapterIndex: Int, queueAdapter: QueueAdapter) {
|
||||||
var index = adapterIndex.dec()
|
var index = adapterIndex.dec()
|
||||||
|
|
Loading…
Reference in a new issue