Я пытаюсь создать приложение для Android с одним действием. У меня есть MainActivity (только активность) с BottomNavigationView, тремя фрагментами верхнего уровня и некоторыми дочерними фрагментами. Мое требование: всякий раз, когда на экране отображаются фрагменты верхнего уровня, нижняя навигация должна быть видна, чтобы было возможно переключение. Но когда я просматриваю любой из дочерних фрагментов, нижняя навигация должна быть скрыта. Есть ли какой-нибудь нестандартный способ использования компонента "Навигация" или необходимо изменить видимость вручную?
Скрыть нижний вид навигации Android для дочерних экранов / фрагментов
Ответы (5)
Вы должны сделать метод в MainActivity для видимости. Вызывайте этот метод из фрагментов, которые вы хотите показать или скрыть.
Одна вещь, с которой я столкнулся с таким сценарием, заключается в том, что видимость нижней навигации не исчезает должным образом. Поэтому я поместил нижний вид навигации в относительный макет и скрыл это родительское представление.
Обновление (компонент навигации 1.0)
Начиная с компонента навигации 1.0.0-alpha08, метод addOnNavigatedListener(controller: NavController, destination: NavDestination)
был изменен на addOnDestinationChangedListener(controller: NavController, destination: NavDestination, arguments: Bundle)
. Его поведение также было немного изменено (оно также вызывается при изменении аргументов адресата).
Старый ответ
Вы можете использовать NavController.OnNavigatedListener для достижения этого поведения (установите его в Activity onCreate):
findNavController(R.id.container).addOnNavigatedListener { _, destination ->
when (destination.id) {
R.id.dashboardFragment -> showBottomNavigation()
else -> hideBottomNavigation()
}
}
private fun hideBottomNavigation() {
// bottom_navigation is BottomNavigationView
with(bottom_navigation) {
if (visibility == View.VISIBLE && alpha == 1f) {
animate()
.alpha(0f)
.withEndAction { visibility = View.GONE }
.duration = EXIT_DURATION
}
}
}
private fun showBottomNavigation() {
// bottom_navigation is BottomNavigationView
with(bottom_navigation) {
visibility = View.VISIBLE
animate()
.alpha(1f)
.duration = ENTER_DURATION
}
}
addOnNavigatedListener
? Я получаю неразрешенную ссылку при попытке ее использовать?
- person IainCunningham; 03.03.2019
addOnNavigatedListener
заменяется на addOnDestinationChangedListener
- person Kalyan Dechiraju; 18.03.2019
EXIT_DURATION
и ENTER_DURATION
?
- person A1m; 26.03.2020
Использование addOnDestinationChangedListener работает, и это решение рекомендуется в официальной документации, но оно вызывает некоторое мерцание, поскольку обратный вызов выполняется до прикрепления фрагмента.
Я считаю, что приведенный ниже ответ более гибкий и лучше обрабатывает анимацию:
supportFragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) {
TransitionManager.beginDelayedTransition(binding.root, Slide(Gravity.BOTTOM).excludeTarget(R.id.nav_host_fragment, true))
when (f) {
is ModalFragment -> {
binding.bottomNavigation.visibility = View.GONE
}
else -> {
binding.bottomNavigation.visibility = View.VISIBLE
}
}
}
}, true)
Вы можете настроить его в зависимости от переходов между вашими фрагментами, выбрав другую анимацию (в моем примере это слайд) или выполнив вызов другого обратного вызова жизненного цикла.
вам просто нужно написать этот код в MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Getting the Navigation Controller
navController = Navigation.findNavController(this, R.id.fragment)
//Setting the navigation controller to Bottom Nav
bottomNav.setupWithNavController(navController)
//Setting up the action bar
NavigationUI.setupActionBarWithNavController(this, navController)
//setting the Bottom navigation visibiliy
navController.addOnDestinationChangedListener { _, destination, _ ->
if(destination.id == R.id.full_screen_destination ){
bottomNav.visibility = View.GONE
}else{
bottomNav.visibility = View.VISIBLE
}
}
}
дополнительные сведения см. в документации для разработчиков Android: Обновите компоненты пользовательского интерфейса с помощью NavigationUI
Таким образом, даже несмотря на то, что на этот вопрос уже был дан ответ, и принятый ответ - тот, который работает, вот код для фактического достижения такого поведения:
Основная деятельность
fun hideBottomNav() {
bottomNavigationView.visibility = View.GONE
}
fun showBottomNav() {
bottomNavigationView.visibility = View.VISIBLE
}
Затем вы вызываете функции в вашем фрагменте onViewCreated()
, onDetach()
function, например:
Фрагмент
class FragmentWithOutBottomNav() : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as MainActivity).hideBottomNav()
}
override fun onDetach() {
super.onDetach()
(activity as MainActivity).showBottomNav()
}
}
Надеюсь, что смогу помочь некоторым людям. Удачного кодирования!