【Android】 ボトムナビゲーションの作り方(Jetpack Compose)

スポンサーリンク

本記事では、Androidアプリ開発における、ボトムナビゲーションの実装方法を解説します。

スポンサーリンク

はじめに

環境

  • Windows 10
  • AndroidStudio Flamingo 2022.2.1.20
  • Google Pixcel5 (Android 14)

新規プロジェクト作成

  • Empty Activity を選択
  • 今回はMy Applicationという名前のプロジェクトにする

以下のサイトを参考に、アプリケーションにコードを追加していきます。

Compose でのナビゲーション  |  Jetpack Compose  |  Android Developers

スポンサーリンク

依存関係の追加

Build.gradleに以下の依存関係を追加します。

implementation "androidx.navigation:navigation-compose:2.7.5"
implementation("androidx.compose.material:material:1.7.1")

MainActivityを以下のように記述します。

package com.example.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.ui.theme.MyApplicationTheme

@OptIn(ExperimentalMaterial3Api::class)
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    val navController = rememberNavController()
                    Scaffold(
                        bottomBar = { BottomNavigationBar(navController = navController) }
                    ) { innerPadding ->
                        NavigationGraph(navController, Modifier.padding(innerPadding))
                    }
                }
            }
        }
    }
}

@Composable
fun BottomNavigationBar(navController: NavHostController) {
    val items = listOf(
        BottomNavItem.Home,
        BottomNavItem.Search,
        BottomNavItem.Profile
    )
    BottomNavigation {
        val currentRoute = navController.currentBackStackEntry?.destination?.route
        items.forEach { item ->
            BottomNavigationItem(
                icon = { Icon(item.icon, contentDescription = item.title) },
                label = { Text(item.title) },
                selected = currentRoute == item.route,
                onClick = {
                    navController.navigate(item.route) {
                        popUpTo(navController.graph.startDestinationId) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )
        }
    }
}

@Composable
fun NavigationGraph(navController: NavHostController, modifier: Modifier = Modifier) {
    NavHost(navController, startDestination = BottomNavItem.Home.route, modifier = modifier) {
        composable(BottomNavItem.Home.route) { HomeScreen() }
        composable(BottomNavItem.Search.route) { SearchScreen() }
        composable(BottomNavItem.Profile.route) { ProfileScreen() }
    }
}


@Composable
fun HomeScreen() {
    Text(text = "Welcome to the Home Screen")
}

@Composable
fun SearchScreen() {
    Text(text = "Welcome to the Search Screen")
}

@Composable
fun ProfileScreen() {
    Text(text = "Welcome to the Profile Screen")
}

sealed class BottomNavItem(val route: String, val icon: ImageVector, val title: String) {
    object Home : BottomNavItem("home", Icons.Filled.Home, "Home")
    object Search : BottomNavItem("search", Icons.Filled.Search, "Search")
    object Profile : BottomNavItem("profile", Icons.Filled.Person, "Profile")
}
スポンサーリンク

よくあるエラー

①NavHostを使おうとするとエラー:Interface NavHost does not have constructorsが発生

import androidx.navigation.NavHostは間違いです。

import androidx.navigation.compose.NavHostが正しいです。

②Scaffoldを使おうとすると、以下のエラーが発生

This material API is experimental and is likely to change or to be removed in the future.

このエラーは。Scaffoldを含むMaterial3 APIが実験的であるために発生しています。@OptInを使用して実験的なAPIを使用することを明示的に許可する必要があります。

コメント