Bundnavigation og faner
Implementér navigation mellem flere sektioner med BottomNavigationView forbundet til NavController samt faner, der kan stryges, med TabLayout, ViewPager2 og TabLayoutMediator.
Bundnavigation og faner er en gratis Android Academy-lektion på CoddyKit. Dette er lektion 5 af 5. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Android Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Android Academy-kurset indeholder 5 lektioner i alt.
Navigationsmønstre
To almindelige mønstre til navigation på øverste niveau i Android-apps:
- Navigation i bunden — til 3–5 primære destinationer. Altid synlig. Bedst til sektioner med samme betydning (f.eks. Hjem, Søgning, Profil).
- Faner — til relateret indhold på en skærm (f.eks. Alle / Aktive / Udførte). Bruges ofte sammen med ViewPager2 for understøttelse af swipe.
Layout for BottomNavigationView
Føj BottomNavigationView og en FragmentContainerView til dit Activity-layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
</LinearLayout>Menupunkter i navigationen i bunden
Definér punkter i res/menu/bottom_nav_menu.xml. ID'et for hvert punkt skal svare til ID'et for en destination i navigationsgrafen:
<!-- res/menu/bottom_nav_menu.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_home"
android:title="Home" />
<item
android:id="@+id/searchFragment"
android:icon="@drawable/ic_search"
android:title="Search" />
<item
android:id="@+id/profileFragment"
android:icon="@drawable/ic_person"
android:title="Profile" />
</menu>Forbindelse til NavController
Forbind BottomNavigationView med NavController i onCreate():
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHost = supportFragmentManager
.findFragmentById(R.id.navHostFragment) as NavHostFragment
val navController = navHost.navController
binding.bottomNav.setupWithNavController(navController)
// Hide bottom nav on detail screens:
navController.addOnDestinationChangedListener { _, destination, _ ->
binding.bottomNav.visibility = when (destination.id) {
R.id.detailFragment -> View.GONE
else -> View.VISIBLE
}
}
}
}Badges i navigationen i bunden
Vis notifikationsbadges på punkter i navigationen i bunden:
// Show a numbered badge:
val badge = binding.bottomNav.getOrCreateBadge(R.id.homeFragment)
badge.number = 5
badge.isVisible = true
// Show dot badge (no number):
val dotBadge = binding.bottomNav.getOrCreateBadge(R.id.searchFragment)
dotBadge.isVisible = true
// Remove badge:
binding.bottomNav.removeBadge(R.id.homeFragment)TabLayout
TabLayout viser vandrette faner og bruges typisk sammen med ViewPager2 til indhold, der kan skubbes:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>ViewPager2 + FragmentStateAdapter
Opret en adapter, der leverer et fragment for hver faneposition:
class TasksPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
override fun getItemCount() = 3
override fun createFragment(position: Int): Fragment = when (position) {
0 -> AllTasksFragment()
1 -> ActiveTasksFragment()
2 -> CompletedTasksFragment()
else -> throw IllegalStateException("Unknown tab $position")
}
}TabLayoutMediator
Forbind ViewPager2 og TabLayout med TabLayoutMediator:
// In Fragment.onViewCreated():
val adapter = TasksPagerAdapter(this)
binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) {
0 -> "All"
1 -> "Active"
2 -> "Done"
else -> ""
}
}.attach()
// Disable swipe if needed:
binding.viewPager.isUserInputEnabled = falseFane med ikoner
Føj ikoner til fanerne i TabLayout:
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
when (position) {
0 -> {
tab.text = "Home"
tab.setIcon(R.drawable.ic_home)
}
1 -> {
tab.text = "Search"
tab.setIcon(R.drawable.ic_search)
}
2 -> {
tab.text = "Profile"
tab.setIcon(R.drawable.ic_person)
}
}
}.attach()Grænse for sider uden for skærmen
Som standard holder ViewPager2 kun nabosiden i hukommelsen. Forøg offscreenPageLimit, hvis dine faner skal forblive aktive, når du skifter:
// Keep 2 pages on each side alive:
binding.viewPager.offscreenPageLimit = 2
// Note: FragmentStateAdapter saves and restores state for off-screen
// fragments even when offscreenPageLimit is 1 (default).
// Only increase this when you need views (not just state) to survive.Navigation i bunden eller faner: Valg
En hurtig vejledning til at vælge det rigtige mønster:
- Brug navigation i bunden, når: der er 3–5 destinationer på øverste niveau med forskellige formål (Hjem, Søgning, Notifikationer, Profil)
- Brug faner, når: du filtrerer eller kategoriserer den samme type indhold (Alle / Aktive / Arkiverede opgaver)
- Kombinér begge: Navigation i bunden til sektioner på øverste niveau og faner i en sektion til underfiltrering
Hurtigt tjek
Hvilken klasse forbinder et TabLayout med en ViewPager2 og angiver fanernes etiketter?
Opsummering: Navigation i bunden og faner
Navigation i apps med flere sektioner, når det gøres rigtigt:
- BottomNavigationView — 3–5 destinationer med samme betydning; menu-ID'er svarer til destinationernes ID'er i navigationsgrafen
setupWithNavController()— automatisk skift af fane og tilbagehistorik- Badges med
getOrCreateBadge() - TabLayout + ViewPager2 — indhold, der kan skubbes, og filtrerede visninger af det samme indhold
TabLayoutMediator— forbinder de to og angiver etiketterne
Næste emne: Enhedstest med JUnit for at holde din kode pålidelig.
Lær Kotlin med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 36
- Lektioner
- 152
Ofte stillede spørgsmål
Er lektionen “Bundnavigation og faner” gratis?
Ja — alle 3 lektioner i læringssporet Android Academy, inklusive “Bundnavigation og faner”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Android Academy-kurset indeholder 5 lektioner i alt.
Hvad lærer jeg i “Bundnavigation og faner”?
Implementér navigation mellem flere sektioner med BottomNavigationView forbundet til NavController samt faner, der kan stryges, med TabLayout, ViewPager2 og TabLayoutMediator. Du øver dig i Android Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Android Academy?
Der kræves ingen tidligere erfaring. Android Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 5 af 5.
Hvor lang tid tager lektionen “Bundnavigation og faner”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Android Academy-lektion?
Ja. Alle Android Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Grundlæggende Material Design
- Temaer og styles
- Brugerdefinerede views
- Animationer og overgange
- Bundnavigation og faner