Почему BottomNavigation отображается на следующей странице в Jetpack Compose?

Я хочу выполнять навигацию с помощью Scaffold и BottomNavigation в Jetpack Compose. Они находятся на главной странице. Но когда я щелкаю контент на MainPage и перехожу к DetailPage, BottomNavigation также существует, как и изображение:

Как я могу скрыть нижнюю навигацию на странице DetailPage?

3 ответа

Вам необходимо указать, какие экраны вы хотите показывать, а какие - нет; В противном случае он будет отображаться на всех экранах внутри Scaffoldтело (которое у вас есть bottomBar). Приведенный ниже код был из моего приложения.

Создайте состояние, которое отслеживает любые изменения пункта назначения на navController

Внутри when вы можете поставить любые экраны, которые хотите показать navigationBar иначе просто установите на

      @Composable
private fun NavController.currentScreen(): State<MainSubScreen> {
    val currentScreen = remember { mutableStateOf<MainSubScreen>(MainSubScreen.Home) }

    DisposableEffect(key1 = this) {
        val listener = NavController.OnDestinationChangedListener { _, destination, _ ->
            when {
                destination.hierarchy.any { it.route == MainSubScreen.Home.route } -> {
                    currentScreen.value = MainSubScreen.Home
                } else -> currentScreen.value = MainSubScreen.NoBottomBar
            }
        }
        addOnDestinationChangedListener(listener)
    }
    return currentScreen
}

На эшафоте, где вы ставите нижнюю панель ур.

так что вы можете проверить, если currentScreen было NoBottomBar если это было, не показывай это

      // initialized currentScreeen above
val currentScreen by navController.currentScreen()

    Scaffold(
        bottomBar = {
            if (currentScreen != MainSubScreen.NoBottomBar) {
                MainBottomNavigation()
            } else Unit
        }
    ) {
        // Your screen
    }

Это зависит от того, где вы разместили свой NavHost. Если он обертывает ваш Scaffold, тогда вы перемещаетесь, что Composable покрывает весь экран

      NavHost(
    navController = navController,
    startDestination = "start_destination"
) {
     composable(route = "start_destination") { ->
        Scaffold(){...}
    }
}

Если NavHost внутри content: @Composable (PaddingValues) -> Unit, когда вы перемещаетесь, пока ваш TopAbbpar, Tabs или BottomNavigation остается на экране

Мне нравится способ сделать это.
Попробуйте использовать ViewModle для управления видимостью BottomNavigation, показать его при входе в MainPage и скрыть при выходе из MainPage

      // ViewModel
class VM: ViewModel() {
  private val _state: MutableLiveData<Boolean> = MutableLiveData(true)
  val state: LiveData<Boolean> get() = _state
  fun setState(status: Boolean) {
      _state.postValue(status)
  }
}


// MainPage
@Compose MainPage(vm: VM) {
  LaunchedEffect(key1 = true) {
    vm.setState(true)
  }

  DisposableEffect(key1 = true) {
    onDispose {
      vm.setState(false)
    }
  }
}


// page contains Scaffold
@Composable
fun Greeting(vm: VM) {
  // State of BottomNavigation`s visibility
  val state = remember { mutableStateOf<Boolean>(true) }
  // read the BottomNavigation`s visibility from ViewModel and send to State
  vm.state.observeAsState().value?.let { state.value = it }

  Scaffold(bottomBar = {
    // show / hide BottomNavigation controlled by State
    state.takeIf { it.value }?.let {
        BottomNavigation {
            list.forEachIndexed { index, label ->
                BottomNavigationItem(
                    label = { Text(text = label) },
                    selected = index == selectedItem.value,
                    onClick = { selectedItem.value = index },
                    icon = {
                        Icon(
                            painter = painterResource(id = R.drawable.ic_launcher_foreground),
                            contentDescription = null
                        )
                    })
            }
        }
    }
  }) {
    NavHost(navController = navController, startDestination = "one") {
        composable(route = "one") { PageList(navController, vm) }
        composable(route = "detail") { PageDetail(vm) }
      }
    }
  }

Если вы не хотите быстро скрывать нижнюю навигацию, вы можете скрыть нижнюю навигацию перед навигацией.