Android Academy · Lektion

Bundnavigation og faner

Implementér navigation mellem flere sektioner med BottomNavigationView forbundet til NavController samt faner, der kan stryges, med TabLayout, ViewPager2 og TabLayoutMediator.

Lektion 5 af 513 trin

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 = false

Fane 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.

Gratis at komme i gang

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

  1. Grundlæggende Material Design
  2. Temaer og styles
  3. Brugerdefinerede views
  4. Animationer og overgange
  5. Bundnavigation og faner
← Tilbage til Android Academy