|
|
||
|---|---|---|
| .. | ||
| src/main | ||
| .gitignore | ||
| README.md | ||
| build.gradle | ||
README.md
tabbar-navigation
Модуль, упрощающий добавление таббара с обособленной навигацией в каждой табе. Данный модуль базируется на классах модуля navigation – NavigationActivity, ViewControllerNavigation, ViewController.
Основные интерфейсы и классы
BottomNavigationActivity – абстрактный класс, наследуемый от класса NavigationActivity и содержащий в себе 2 объекта:
navigation– объект, используемый для навигации на уровнеActivity. При работе с навигацией используя этот объект таббар скрывается на открываемом экране, и переключиться на какую-нибудь другую табу нельзя.innerNavigation– объект, используемый для навигации вннутри табы. При работе с навигацией используя этот объект таббар остается видимым на открываемом экране, таким образом сохраняя возможность переключаться по остальным табам таббара.
BottomNavigationFragment – абстраткный класс, наследуемый от Fragment и содержащий в себе логику по настройке навигации используя вложенный объект BottomNavigationController.
Последовательность необходимых действий для организации навигации:
-
Отнаследовать главную
Activityприложения отBottomNavigationActivityи переопределить следующие поля:fragmentContainerViewId– идентификаторViewкорневого контейнера фрагментов главнойActivity
-
Отнаследовать контейнерный
Fragmentприложения от BottomNavigationFragment и переопределить следующие поля:-
rootLayoutId– идентификаторLayoutкорневого фрагмента. -
navigationContainerViewId– идентификаторViewконтейнера таббара внутриLayoutкорневого фрагмента. -
contentContainerViewId– идентификаторViewконтейнера содержимого каждой табы внутриLayoutкорневого фрагмента. -
contentContainerLayoutId– идентификаторLayoutконтейнера содержимого каждой табы. -
topLevelViewControllerId– идентификаторViewкнопки главной табы внутриViewконтейнера таббара. -
wrapWithNavigationContainer– параметр, отвечающий за необходимость добавления обособленной навигации в каждой табе. Если онfalse, то в приложении будет навигация только на уровне главнойActivity. -
navigationViewControllers: SparseArray<Pair<Class<out ViewController<*, *>>, Parcelable>>–SparseArrayс идентификаторамиViewкнопок каждой табы в качестве ключей и парыViewControllerClass to ViewControllerStateв качестве значений.Количество кнопок в таббаре может быть произвольным
-
Дополнительно
-
В классе
BottomNavigationFragmentможно также переопределить полеreselectListener, отвечающее за повторное нажатие на уже открытую табу. По умолчанию происходит переход к низу стека фрагментов открытой табы –getNavigationActivity().innerNavigation.up() -
Объекты
innerNavigationв классеBottomNavigationActivityиnavigationв классеNavigationActivityпомечены какopen, давая тем самым возможность добавить кастомную логику переопределив их. -
В случае, если открыта любая таба кроме главной (
topLevelViewControllerId) со значениемbackStackEntryCount = 0, нажатие на системную кнопку "Назад" предварительно откроет главную табу, прежде чем отработает действие кнопки по умолчанию.
Примеры
Файл MainActivity.kt
class MainActivity : BottomNavigationActivity() {
override val fragmentContainerViewId = R.id.fragment_container
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_container)
if (savedInstanceState == null) {
navigation.setInitial(MainFragment::class.java)
}
}
}
Файл MainFragment.kt
class MainFragment : BottomNavigationFragment() {
override val rootLayoutId = R.layout.fragment_main
override val navigationContainerViewId = R.id.navigation_tabs_container
override val contentContainerViewId = R.id.fragment_container
override val contentContainerLayoutId = R.layout.fragment_container
override val topLevelViewControllerId = R.id.navigation_main
override val wrapWithNavigationContainer = true
override val navigationViewControllers = SparseArray<Pair<Class<out ViewController<*, *>>, Parcelable>>().apply {
put(R.id.navigation_main, MainViewController::class.java to MainState())
put(R.id.navigation_second, SecondViewController::class.java to SecondState())
put(R.id.navigation_third, ThirdViewController::class.java to ThirdState())
}
}
Файл MainViewController.kt
class MainViewController(
creationContext: CreationContext
) : ViewController<MainActivity, MainState>(
creationContext,
R.layout.view_controller_main
) {
private val navigateInsideTabbarButton: View = findViewById(R.id.view_controller_main_button_inside)
private val navigateOutsideTabbarButton: View = findViewById(R.id.view_controller_main_button_outside)
init {
//navigate using innerNavigation and saving tabbar visible
navigateInsideTabbarButton.setOnClickListener {
activity.innerNavigation.pushViewController(
TutorialViewController::class.java,
EmptyState
)
}
//navigate using navigation and making tabbar invisible
navigateOutsideTabbarButton.setOnClickListener {
activity.navigation.pushViewController(
TutorialViewController::class.java,
EmptyState
)
}
}
}
Зависимости
Поскольку модуль базируется на классах модуля navigation, то необходимо подключить его.
implementation project(':navigation')