Highlight current tab in navigation drawer

This commit is contained in:
Kirill Kamakin
2022-11-20 10:36:26 +01:00
parent 7d43e1afc2
commit 6c3abbd51c
9 changed files with 42 additions and 19 deletions

View File

@@ -8,6 +8,7 @@ import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.appcompat.widget.SearchView.OnQueryTextListener
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.iterator
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDirections import androidx.navigation.NavDirections
@@ -65,11 +66,16 @@ class MainActivity : AppCompatActivity(R.layout.main_activity) {
isAppearanceLightNavigationBars = isAppearanceLightBars isAppearanceLightNavigationBars = isAppearanceLightBars
isAppearanceLightStatusBars = isAppearanceLightBars isAppearanceLightStatusBars = isAppearanceLightBars
} }
setupSearchItem(binding.toolbar.menu.findItem(R.id.search_recipe_action))
viewModel.uiStateLive.observe(this, ::onUiStateChange) viewModel.uiStateLive.observe(this, ::onUiStateChange)
} }
private fun onNavigationItemSelected(menuItem: MenuItem): Boolean { private fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
logger.v { "onNavigationItemSelected() called with: menuItem = $menuItem" } logger.v { "onNavigationItemSelected() called with: menuItem = $menuItem" }
if (menuItem.isChecked) {
logger.d { "Not navigating because it is the current destination" }
return true
}
val directions = when (menuItem.itemId) { val directions = when (menuItem.itemId) {
R.id.add_recipe -> actionGlobalAddRecipeFragment() R.id.add_recipe -> actionGlobalAddRecipeFragment()
R.id.recipes_list -> actionGlobalRecipesListFragment() R.id.recipes_list -> actionGlobalRecipesListFragment()
@@ -77,20 +83,24 @@ class MainActivity : AppCompatActivity(R.layout.main_activity) {
R.id.login -> actionGlobalAuthenticationFragment() R.id.login -> actionGlobalAuthenticationFragment()
R.id.logout -> { R.id.logout -> {
viewModel.logout() viewModel.logout()
binding.drawer.close()
return true return true
} }
else -> throw IllegalArgumentException("Unknown menu item id: ${menuItem.itemId}") else -> throw IllegalArgumentException("Unknown menu item id: ${menuItem.itemId}")
} }
menuItem.isChecked = true
navigateTo(directions) navigateTo(directions)
return true return true
} }
private fun onUiStateChange(uiState: MainActivityUiState) { private fun onUiStateChange(uiState: MainActivityUiState) {
logger.v { "onUiStateChange() called with: uiState = $uiState" } logger.v { "onUiStateChange() called with: uiState = $uiState" }
with(binding.navigationView) { for (menuItem in binding.navigationView.menu.iterator()) {
menu.findItem(R.id.logout).isVisible = uiState.canShowLogout val itemId = menuItem.itemId
menu.findItem(R.id.login).isVisible = uiState.canShowLogin when (itemId) {
R.id.logout -> menuItem.isVisible = uiState.canShowLogout
R.id.login -> menuItem.isVisible = uiState.canShowLogin
}
menuItem.isChecked = itemId == uiState.checkedMenuItemId
} }
if (uiState.navigationVisible) { if (uiState.navigationVisible) {
@@ -101,11 +111,7 @@ class MainActivity : AppCompatActivity(R.layout.main_activity) {
binding.toolbar.navigationIcon = null binding.toolbar.navigationIcon = null
} }
binding.toolbar.menu.findItem(R.id.search_recipe_action).isVisible = uiState.searchVisible
binding.toolbar.menu.findItem(R.id.search_recipe_action).apply {
isVisible = uiState.searchVisible
setupSearchItem(this)
}
} }
private fun setupSearchItem(searchItem: MenuItem) { private fun setupSearchItem(searchItem: MenuItem) {

View File

@@ -1,9 +1,12 @@
package gq.kirmanak.mealient.ui.activity package gq.kirmanak.mealient.ui.activity
import androidx.annotation.IdRes
data class MainActivityUiState( data class MainActivityUiState(
val isAuthorized: Boolean = false, val isAuthorized: Boolean = false,
val navigationVisible: Boolean = false, val navigationVisible: Boolean = false,
val searchVisible: Boolean = false, val searchVisible: Boolean = false,
@IdRes val checkedMenuItemId: Int? = null,
) { ) {
val canShowLogin: Boolean get() = !isAuthorized val canShowLogin: Boolean get() = !isAuthorized

View File

@@ -38,7 +38,11 @@ class AddRecipeFragment : Fragment(R.layout.fragment_add_recipe) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" } logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" }
activityViewModel.updateUiState { activityViewModel.updateUiState {
it.copy(navigationVisible = true, searchVisible = false) it.copy(
navigationVisible = true,
searchVisible = false,
checkedMenuItemId = R.id.add_recipe,
)
} }
viewModel.loadPreservedRequest() viewModel.loadPreservedRequest()
setupViews() setupViews()

View File

@@ -32,7 +32,7 @@ class AuthenticationFragment : Fragment(R.layout.fragment_authentication) {
logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" } logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" }
binding.button.setOnClickListener { onLoginClicked() } binding.button.setOnClickListener { onLoginClicked() }
activityViewModel.updateUiState { activityViewModel.updateUiState {
it.copy(navigationVisible = true, searchVisible = false) it.copy(navigationVisible = true, searchVisible = false, checkedMenuItemId = R.id.login)
} }
viewModel.uiState.observe(viewLifecycleOwner, ::onUiStateChange) viewModel.uiState.observe(viewLifecycleOwner, ::onUiStateChange)
} }
@@ -61,7 +61,7 @@ class AuthenticationFragment : Fragment(R.layout.fragment_authentication) {
private fun onUiStateChange(uiState: OperationUiState<Unit>) = with(binding) { private fun onUiStateChange(uiState: OperationUiState<Unit>) = with(binding) {
logger.v { "onUiStateChange() called with: authUiState = $uiState" } logger.v { "onUiStateChange() called with: authUiState = $uiState" }
if (uiState.isSuccess) { if (uiState.isSuccess) {
findNavController().popBackStack() findNavController().navigateUp()
return return
} }

View File

@@ -36,7 +36,11 @@ class BaseURLFragment : Fragment(R.layout.fragment_base_url) {
binding.button.setOnClickListener(::onProceedClick) binding.button.setOnClickListener(::onProceedClick)
viewModel.uiState.observe(viewLifecycleOwner, ::onUiStateChange) viewModel.uiState.observe(viewLifecycleOwner, ::onUiStateChange)
activityViewModel.updateUiState { activityViewModel.updateUiState {
it.copy(navigationVisible = !args.isOnboarding, searchVisible = false) it.copy(
navigationVisible = !args.isOnboarding,
searchVisible = false,
checkedMenuItemId = R.id.change_url,
)
} }
} }

View File

@@ -58,7 +58,7 @@ class DisclaimerFragment : Fragment(R.layout.fragment_disclaimer) {
} }
viewModel.startCountDown() viewModel.startCountDown()
activityViewModel.updateUiState { activityViewModel.updateUiState {
it.copy(navigationVisible = false, searchVisible = false) it.copy(navigationVisible = false, searchVisible = false, checkedMenuItemId = null)
} }
} }
} }

View File

@@ -49,7 +49,11 @@ class RecipesListFragment : Fragment(R.layout.fragment_recipes_list) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" } logger.v { "onViewCreated() called with: view = $view, savedInstanceState = $savedInstanceState" }
activityViewModel.updateUiState { activityViewModel.updateUiState {
it.copy(navigationVisible = true, searchVisible = true) it.copy(
navigationVisible = true,
searchVisible = true,
checkedMenuItemId = R.id.recipes_list
)
} }
setupRecipeAdapter() setupRecipeAdapter()
hideKeyboardOnScroll() hideKeyboardOnScroll()

View File

@@ -2,21 +2,25 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/recipes_list" android:id="@+id/recipes_list"
android:checkable="true"
android:icon="@drawable/ic_list" android:icon="@drawable/ic_list"
android:title="@string/menu_navigation_drawer_recipes_list" /> android:title="@string/menu_navigation_drawer_recipes_list" />
<item <item
android:id="@+id/add_recipe" android:id="@+id/add_recipe"
android:checkable="true"
android:icon="@drawable/ic_add" android:icon="@drawable/ic_add"
android:title="@string/menu_navigation_drawer_add_recipe" /> android:title="@string/menu_navigation_drawer_add_recipe" />
<item <item
android:id="@+id/change_url" android:id="@+id/change_url"
android:checkable="true"
android:icon="@drawable/ic_change" android:icon="@drawable/ic_change"
android:title="@string/menu_navigation_drawer_change_url" /> android:title="@string/menu_navigation_drawer_change_url" />
<item <item
android:id="@+id/login" android:id="@+id/login"
android:checkable="true"
android:icon="@drawable/ic_login" android:icon="@drawable/ic_login"
android:title="@string/menu_navigation_drawer_login" /> android:title="@string/menu_navigation_drawer_login" />

View File

@@ -51,8 +51,7 @@
<action <action
android:id="@+id/action_baseURLFragment_to_recipesListFragment" android:id="@+id/action_baseURLFragment_to_recipesListFragment"
app:destination="@id/recipesListFragment" app:destination="@id/recipesListFragment"
app:popUpTo="@id/nav_graph" app:popUpTo="@id/nav_graph" />
app:popUpToInclusive="true" />
<argument <argument
android:name="isOnboarding" android:name="isOnboarding"
app:argType="boolean" /> app:argType="boolean" />
@@ -66,8 +65,7 @@
<action <action
android:id="@+id/action_global_authenticationFragment" android:id="@+id/action_global_authenticationFragment"
app:destination="@id/authenticationFragment" app:destination="@id/authenticationFragment" />
app:popUpTo="@id/recipesListFragment" />
<action <action
android:id="@+id/action_global_recipesListFragment" android:id="@+id/action_global_recipesListFragment"