Android 如何使用新的导航体系结构组件实现具有BottomNavigationView的ViewPager?
我有一个带有Android 如何使用新的导航体系结构组件实现具有BottomNavigationView的ViewPager?,android,android-architecture-components,Android,Android Architecture Components,我有一个带有BottomNavigationView和ViewPager的应用程序。 如何使用新的“导航架构组件”实现它 最佳做法是什么 非常感谢我们可以使用底部导航组件和NavigationGraph轻松实现 您应该为每个底部导航菜单创建相应的片段 nav_graph.xml <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk
BottomNavigationView
和ViewPager
的应用程序。
如何使用新的“导航架构组件”实现它
最佳做法是什么
非常感谢我们可以使用底部导航组件和NavigationGraph轻松实现 您应该为每个底部导航菜单创建相应的片段 nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/actionHome">
<fragment
android:id="@+id/actionHome"
android:name="com.sample.demo.fragments.Home"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/toExplore"
app:destination="@id/actionExplore" />
</fragment>
<fragment
android:id="@+id/actionExplore"
android:name="com.sample.demo.fragments.Explore"
android:label="fragment_explore"
tools:layout="@layout/fragment_explore" />
<fragment
android:id="@+id/actionBusiness"
android:name="com.sample.demo.fragments.Business"
android:label="fragment_business"
tools:layout="@layout/fragment_business" />
<fragment
android:id="@+id/actionProfile"
android:name="com.sample.demo.fragments.Profile"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
</navigation>
干杯 更新(15/06/21):
从导航组件版本开始,支持开箱即用的多个后台堆栈。根据文档,如果您将NavigationView
或BottomNavigationView
与导航组件一起使用,那么多个后台堆栈应该可以工作,而不会对以前的实现进行任何代码更改
作为此更改的一部分,onNavDestinationSelected()、BottomNavigationView.setupWithNavController()和NavigationView.setupWithNavController()的NavigationUI方法现在会自动保存和恢复弹出目标的状态,从而支持多个后台堆栈,而无需任何代码更改。当使用片段导航时,建议使用这种方法来集成多个后台堆栈
原始答案:
带有导航拱组件的BottomNavigationView
的默认实现对我来说不起作用。单击选项卡时,它会根据导航图从头开始
我需要在屏幕底部有5个选项卡,每个选项卡都有一个单独的后堆栈。这意味着在标签之间切换时,您将始终返回与离开前完全相同的状态(如Instagram)
我的做法如下:
ViewPager
和BottomNavigationView
放入activity\u main.xml
MainActivity.kt中的OnNavigationItemSelectedListener
设置为BottomNavigationView
NavHostFragment
setupWithNavController()
,而不将其设置为supportActionBar
。这样,工具栏标题将自动更新,备份/备份按钮将自动管理
结果:
- ViewPager存储每个选项卡的状态
- 不担心片段事务
和SafeArgs
按预期工作DeepLinking
- 我们可以完全控制
和BottomNavigationManager
(即,我们可以实现ViewPager
,并决定在弹出堆栈之前将当前选项卡中的列表滚动到顶部)OnNavigationItemReselectedListener
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/main_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/main_bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Tab1ContainerFragment">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tab_1_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="@+id/tab_1_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph_tab_1" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_dashboard"
app:startDestination="@id/dashboardFragment1">
<fragment
android:id="@+id/dashboardFragment1"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment1"
android:label="DashboardFragment1"
tools:layout="@layout/fragment_dashboard1">
<action
android:id="@+id/action_dashboardFragment1_to_dashboardFragment2"
app:destination="@id/dashboardFragment2" />
</fragment>
<fragment
android:id="@+id/dashboardFragment2"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment2"
android:label="DashboardFragment2"
tools:layout="@layout/fragment_dashboard2">
<action
android:id="@+id/action_dashboardFragment2_to_dashboardFragment3"
app:destination="@id/dashboardFragment3" />
</fragment>
<fragment
android:id="@+id/dashboardFragment3"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment3"
android:label="DashboardFragment3"
tools:layout="@layout/fragment_dashboard3" >
<action
android:id="@+id/action_dashboardFragment3_to_dashboardFragment1"
app:destination="@id/dashboardFragment1"
app:popUpTo="@id/dashboardFragment1"
app:popUpToInclusive="true" />
</fragment>
</navigation>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_graph_home"
android:icon="@drawable/ic_baseline_home_24"
android:title="Home"/>
<item
android:id="@+id/nav_graph_dashboard"
android:icon="@drawable/ic_baseline_dashboard_24"
android:title="Dashboard"/>
<item
android:id="@+id/nav_graph_notification"
android:icon="@drawable/ic_baseline_notifications_24"
android:title="Notification"/>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nested_nav_host_fragment_home"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_home"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
ViewPagerAdapter.kt
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var viewPagerAdapter: ViewPagerAdapter
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_tab_1 -> {
main_view_pager.currentItem = 0
return@OnNavigationItemSelectedListener true
}
R.id.navigation_tab_2 -> {
main_view_pager.currentItem = 1
return@OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
main_view_pager.adapter = viewPagerAdapter
main_bottom_navigation_view.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
}
class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> Tab1ContainerFragment()
else -> Tab2ContainerFragment()
}
}
override fun getCount(): Int {
return 2
}
}
class Tab1ContainerFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_tab_1_container, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<Toolbar>(R.id.tab_1_toolbar)
val navHostFragment = childFragmentManager.findFragmentById(R.id.tab_1_nav_host_fragment) as NavHostFragment? ?: return
val navController = navHostFragment.navController
val appBarConfig = AppBarConfiguration(navController.graph)
toolbar.setupWithNavController(navController, appBarConfig)
}
}
fragment\u tab\u 1\u container.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/main_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/main_bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Tab1ContainerFragment">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tab_1_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="@+id/tab_1_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph_tab_1" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_dashboard"
app:startDestination="@id/dashboardFragment1">
<fragment
android:id="@+id/dashboardFragment1"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment1"
android:label="DashboardFragment1"
tools:layout="@layout/fragment_dashboard1">
<action
android:id="@+id/action_dashboardFragment1_to_dashboardFragment2"
app:destination="@id/dashboardFragment2" />
</fragment>
<fragment
android:id="@+id/dashboardFragment2"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment2"
android:label="DashboardFragment2"
tools:layout="@layout/fragment_dashboard2">
<action
android:id="@+id/action_dashboardFragment2_to_dashboardFragment3"
app:destination="@id/dashboardFragment3" />
</fragment>
<fragment
android:id="@+id/dashboardFragment3"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment3"
android:label="DashboardFragment3"
tools:layout="@layout/fragment_dashboard3" >
<action
android:id="@+id/action_dashboardFragment3_to_dashboardFragment1"
app:destination="@id/dashboardFragment1"
app:popUpTo="@id/dashboardFragment1"
app:popUpToInclusive="true" />
</fragment>
</navigation>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_graph_home"
android:icon="@drawable/ic_baseline_home_24"
android:title="Home"/>
<item
android:id="@+id/nav_graph_dashboard"
android:icon="@drawable/ic_baseline_dashboard_24"
android:title="Dashboard"/>
<item
android:id="@+id/nav_graph_notification"
android:icon="@drawable/ic_baseline_notifications_24"
android:title="Notification"/>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nested_nav_host_fragment_home"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_home"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
但我们需要为每个选项卡创建一个单独的图表:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_graph_tab_1"
app:startDestination="@id/tab1StartFragment">
<fragment
android:id="@+id/tab1StartFragment"
android:name="com.marat.android.bottomnavigationtutorial.Tab1StartFragment"
android:label="fragment_tab_1_start"
tools:layout="@layout/fragment_tab_1_start">
<action
android:id="@+id/action_tab_1_to_content"
app:destination="@id/navigation_graph_content" />
</fragment>
<include app:graph="@navigation/navigation_graph_content" />
</navigation>
这里的“开始-目的地”片段是您希望在选项卡中显示为第一个屏幕的任何片段。我已经使用viewpager实现了Android Arch导航。请看一看。欢迎任何改进。让我们一起学习
我的解决方案是将ViewPager中的片段保留在导航之外,并直接在页面片段上设置操作,就好像这些页面是主机一样。
为了更好地解释它:
假设您在片段A中,有一个片段B的ViewPager
你试着从B导航到C
在片段B中,使用一个Directions类和一个action from A to C.findNavHost().navigateTo(adDirections.ActionFromAtoC)我已经写过了,特别关注主细节片段,这些片段是选项卡式的,但同样的逻辑适用于常规的ViewPager。代码是。我有一个main片段,它在一个viewPager中承载片段a、片段B和片段C
我想从片段B中打开片段D(由MainFragment内的viewPager托管)
所以我创建了一个从MainFragment到片段D的动作,并从片段B调用
val direction = FragmentMainDirections.actionFragmentMainToFragmentD()
findNavController().navigate(direction)
工作 除了Marat的答案之外,为了让back stack在每个片段中使用back按钮,您必须将其添加到您的容器片段onViewCreated中:
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (!navHostFragment.navController.popBackStack()) {
isEnabled = false
activity?.onBackPressed()
}
}
}
activity?.onBackPressedDispatcher?.addCallback(this, callback)
多亏了@Marat-他提供了很好的解决方案。
在我的例子中,我为第二个ViewPager的视图提供了列表/详细视图导航,并使用全屏显示模式,无需任何操作\工具栏:
想要评论一些时刻:
1) 对于我来说,在一个页面上使用一个通用图形是可能的,也是很容易的:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/page2Coordinator"
app:startDestination="@id/Fragment_2Coordinator">
<fragment
android:id="@+id/Fragment_2Coordinator"
android:name="my.app.Fragment_2Coordinator"
android:label="Fragment_2Coordinator">
<action
android:id="@+id/action_showList_2A"
app:destination="@id/Fragment_2A" />
</fragment>
<fragment
android:id="@+id/Fragment_2A"
android:name="my.app.Fragment_2A"
android:label="Fragment_2A">
<action
android:id="@+id/action_goToDetail_2B"
app:destination="@id/Fragment_2B" />
</fragment>
<fragment
android:id="@+id/Fragment_2B"
android:name="my.app.Fragment_2B"
android:label="Fragment_2B">
<action
android:id="@+id/action_backToList_2A"
app:destination="@id/Fragment_2A" />
</fragment>
</navigation>
3) 要使用电话后退按钮从2B返回2A,请转至活动:
class MainActivity : AppCompatActivity() {
. . . . .
override fun onBackPressed() {
val navController = findNavController(R.id.tab_1_nav_host_fragment)
when(navController.currentDestination?.id) {
R.id.Fragment_2B -> {
navController.navigate(R.id.action_backToList_2A)
}
else -> {
super.onBackPressed()
}
}
println()
}
}
我创建了一个在活动上有工具栏的示例,您还可以创建具有自己工具栏的ViewPager片段。它使用OnBackPressedCallback
进行后台导航,ViewModel
设置当前NavController
和NavHostFragment
与childFragmentManager
或嵌套片段,并使用viewLifeCycleOwner尊重生命周期,在暂停时禁用回调并启用onResume
导航和布局架构
MainActivity(Appbar + Toolbar + ViewPager2 + BottomNavigationView)
|
|- HomeNavHostFragment
| |- HF1 -> HF2 -> HF3
|
|- DashboardNavHostFragment
| |- DF1 -> DF2 -> DF3
|
|- NotificationHostFragment
|- NF1 -> NF2 -> NF3
首先,为ViewPager2
nav\u graph\u home.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/main_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/main_bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Tab1ContainerFragment">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tab_1_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="@+id/tab_1_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph_tab_1" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_dashboard"
app:startDestination="@id/dashboardFragment1">
<fragment
android:id="@+id/dashboardFragment1"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment1"
android:label="DashboardFragment1"
tools:layout="@layout/fragment_dashboard1">
<action
android:id="@+id/action_dashboardFragment1_to_dashboardFragment2"
app:destination="@id/dashboardFragment2" />
</fragment>
<fragment
android:id="@+id/dashboardFragment2"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment2"
android:label="DashboardFragment2"
tools:layout="@layout/fragment_dashboard2">
<action
android:id="@+id/action_dashboardFragment2_to_dashboardFragment3"
app:destination="@id/dashboardFragment3" />
</fragment>
<fragment
android:id="@+id/dashboardFragment3"
android:name="com.smarttoolfactory.tutorial7_1bnw_viewpager2_nestednavigation.blankfragment.DashboardFragment3"
android:label="DashboardFragment3"
tools:layout="@layout/fragment_dashboard3" >
<action
android:id="@+id/action_dashboardFragment3_to_dashboardFragment1"
app:destination="@id/dashboardFragment1"
app:popUpTo="@id/dashboardFragment1"
app:popUpToInclusive="true" />
</fragment>
</navigation>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_graph_home"
android:icon="@drawable/ic_baseline_home_24"
android:title="Home"/>
<item
android:id="@+id/nav_graph_dashboard"
android:icon="@drawable/ic_baseline_dashboard_24"
android:title="Dashboard"/>
<item
android:id="@+id/nav_graph_notification"
android:icon="@drawable/ic_baseline_notifications_24"
android:title="Notification"/>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nested_nav_host_fragment_home"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_home"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
主要活动的布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/menu_bottom_nav" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>