I have tried virtually all the answers found in:
but it doesn't work well:
I have a single activity:
activity_main.xml
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" >
</androidx.fragment.app.FragmentContainerView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottom_controls"
android:layout_width="match_parent"
android:layout_height="72dp"
android:onClick="onSongInfoClick"
android:background="@drawable/lyt_rounded_bottom_music"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:elevation="25dp"
app:layout_constraintTop_toBottomOf="@id/nav_host_fragment">
So, Inside the nav_graph, The start destination is a ViewPagerFragment consisting of various tabs.
Now, my first destination in the ViewPager is - SongsFragment
When I click the bottom_controls view from activity_main I am navigating to SongDetailsFragment like this:
MainActivity.kt
//on click song details
fun onSongInfoClick(v: View) {
val navController = findNavController(R.id.nav_host_fragment)
navController.navigateUp() // to clear previous navigation history
navController.navigate(R.id.songDetailsFragment)
}
Here is what I want:
When in SongDetailsFragment:
- Hide the bottom_controls in activity_main
When in other places:
- Show the bottom_controls in activity_main
Right now: This is the current behaviour.
It works for the first time, but on subsequent trial, it doesn't work, as you can see:
- The first time I clicked the bottom_controls, it was hidden in the songDetailsFragment (as it should), but subsequently it shows when in songDetailsFragment.
Here is how I am hiding/showing the bottom_control view:
In MainActivity.kt
songDetailViewModel.currentData.observe(this) {
if (it.id !in arrayOf(0L, -1L, -2L)) {
if (getCurrentVisibleFragment(this) == null){
viewModel.showMiniPlayer()
} else viewModel.hideMiniPlayer()
} else viewModel.hideMiniPlayer()
}
In SongDetailsFragment.kt
class SongDetailsFragment : BaseSongDetailFragment() {
.....
}
BaseSongDetailsFragment.kt
open class BaseSongDetailFragment : Fragment() {
private val songDetailViewModel by sharedViewModel<SongDetailViewModel>()
protected val mainViewModel by inject<MainViewModel>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
showHideBottomSheet()
}
override fun onPause() {
showHideBottomSheet()
super.onPause()
}
override fun onResume() {
showHideBottomSheet()
super.onResume()
}
private fun showHideBottomSheet() {
val currentData = songDetailViewModel.currentData.value ?: return
if (currentData.id == 0L) return
if (GeneralUtility.getCurrentVisibleFragment(requireActivity()) == SongDetailsFragment()){
mainViewModel.hideMiniPlayer()
}
else{
mainViewModel.showMiniPlayer()
}
}
}
And finally, this is the getCurrentVisibleFragment() function
//check if song details fragment
fun getCurrentVisibleFragment(activity: Activity): SongDetailsFragment? {
val navHostFragment = (activity as FragmentActivity).supportFragmentManager.primaryNavigationFragment as NavHostFragment
val fragmentManager: FragmentManager = navHostFragment.childFragmentManager
val songDetailsFragment: Fragment? = fragmentManager.primaryNavigationFragment
return if (songDetailsFragment is SongDetailsFragment) {
songDetailsFragment as SongDetailsFragment
} else null
}