[Android] Jetpack Compose Navigation

Jetpack Compose Navigation(複雑版サンプル)

ポイントは次の 4 つ:
NavHost + NavController
複数画面(Home → Detail → Settings)
パラメーター付きルート(Detail/{itemId})
戻る動作(popBackStack

MainActivity.kt
└─ HomeScreen
└─ DetailScreen
└─ SettingsScreen

package com.example.navigationdemo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.navigation.NavType
import androidx.navigation.compose.*
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NavigationApp()
        }
    }
}

@Composable
fun NavigationApp() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        // ① Home
        composable("home") {
            HomeScreen(
                onSelectItem = { itemId ->
                    navController.navigate("detail/$itemId")
                },
                onOpenSettings = {
                    navController.navigate("settings")
                }
            )
        }

        // ② Detail(パラメータ付き)
        composable(
            route = "detail/{itemId}",
            arguments = listOf(
                navArgument("itemId") { type = NavType.IntType }
            )
        ) { backStackEntry ->
            val id = backStackEntry.arguments?.getInt("itemId")
            DetailScreen(
                itemId = id ?: 0,
                onBack = { navController.popBackStack() }
            )
        }

        // ③ Settings
        composable("settings") {
            SettingsScreen(
                onBack = { navController.popBackStack() }
            )
        }
    }
}

@Composable
fun HomeScreen(onSelectItem: (Int) -> Unit, onOpenSettings: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Home Screen", style = MaterialTheme.typography.headlineMedium)

        Button(onClick = { onSelectItem(10) }) {
            Text("Go to Detail (itemId = 10)")
        }

        Button(onClick = onOpenSettings) {
            Text("Go to Settings")
        }
    }
}

@Composable
fun DetailScreen(itemId: Int, onBack: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Detail Screen", style = MaterialTheme.typography.headlineMedium)
        Text("itemId = $itemId")

        Button(onClick = onBack) {
            Text("Back")
        }
    }
}

@Composable
fun SettingsScreen(onBack: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize().padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text("Settings Screen", style = MaterialTheme.typography.headlineMedium)

        Button(onClick = onBack) {
            Text("Back")
        }
    }
}