ボタンを押して画面遷移する


新しくもう一つ画面(Composablesな関数)を作成し、ボタンを押すとその新しい画面に遷移するように設定しましょう。
以下のステップで進めます。
- 新しいComposable関数(画面)を作成する
新しい画面として表示するComposable関数を定義します。 - NavController をセットアップする
画面遷移を管理するための NavController を設定します。 - ナビゲーショングラフを定義する
どの画面からどの画面へ遷移できるかを定義します。 - ボタンから画面遷移をトリガーする
ボタンの onClick イベントで NavController を使って新しい画面に遷移させます。
具体的な手順
MainActivity.kt ファイル(または新しいファイルを作成しても良いですが、最初は同じファイルで進めましょう)を編集します。
1. 必要なimportを追加
ファイルの先頭あたりに、以下を追加してください。(既にあるものもあるかもしれません)
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.compose.material3.Scaffold // 画面全体の基本レイアウト用
import androidx.compose.material3.ExperimentalMaterial3Api // Scaffoldで必要
import androidx.compose.material3.TopAppBar // 上部のバー
import androidx.compose.material3.Text
import androidx.compose.material3.Button
import androidx.compose.foundation.layout.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.dp
import androidx.compose.ui.Modifier
2. 新しい画面(Composable関数)を作成する
MainActivity.kt の下の方、またはどこか新しいComposable関数として、新しい画面を定義します。
@Composable
fun SecondScreen(navController: NavController) {
Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "これは2番目の画面です!", modifier = Modifier.padding(bottom = 24.dp))
Button(onClick = { navController.popBackStack() }) { // 戻るボタン
Text("最初の画面に戻る")
}
}
}
- navController: NavController を引数で受け取ることで、この画面から他の画面へ遷移したり、前の画面に戻ったりできるようになります。
- navController.popBackStack() は、一つ前の画面に戻るための関数です。
3. MainActivity の setContent ブロックを修正してナビゲーションを設定する
MainActivity.kt の onCreate メソッドの中の setContent ブロックを以下のように修正します。
@OptIn(ExperimentalMaterial3Api::class) // Scaffoldで必要になる可能性
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
YourAppNameTheme { // あなたのアプリのテーマ
val navController = rememberNavController() // NavControllerをインスタンス化
Scaffold(
topBar = {
TopAppBar(title = { Text("画面遷移アプリ") })
}
) { paddingValues -> // paddingValuesでAppBarの高さ分のパディングを自動的に適用
NavHost(
navController = navController,
startDestination = "first_screen", // 最初に表示する画面のルート名
modifier = Modifier.padding(paddingValues) // AppBarの分だけ下にずらす
) {
// 最初の画面
composable("first_screen") {
FirstScreen(navController = navController, name = "Android")
}
// 2番目の画面
composable("second_screen") {
SecondScreen(navController = navController)
}
}
}
}
}
}
}
- rememberNavController(): 画面遷移を管理する NavController のインスタンスを作成します。
- NavHost: 画面遷移をホストするコンポーザブルです。navController と startDestination(最初に表示する画面のルート名)を指定します。
- composable(“ルート名”) { … }: ナビゲーショングラフのエントリポイントを定義します。”first_screen” や “second_screen” といった文字列で各画面を識別します。
4. 既存の Greeting 関数を FirstScreen にリネームし、NavController を受け取るように修正
前の手順で作成した Greeting 関数(「Hello Android」とボタンがあった画面)を、FirstScreen という名前に変更し、NavController を引数で受け取るように修正します。そして、ボタンのクリックイベントで navController.navigate(“second_screen”) を呼び出します。
@Composable
fun FirstScreen(navController: NavController, name: String, modifier: Modifier = Modifier) {
Column(
modifier = modifier.fillMaxSize().padding(16.dp), // fillMaxSizeで画面全体に広げる
verticalArrangement = Arrangement.Center, // 垂直方向中央寄せ
horizontalAlignment = Alignment.CenterHorizontally // 水平方向中央寄せ
) {
Text(
text = "こんにちは、$name!",
modifier = Modifier.padding(bottom = 24.dp)
)
Button(onClick = {
// ボタンがクリックされたら、"second_screen"へ遷移する
navController.navigate("second_screen")
}) {
Text("2番目の画面へ")
}
}
}
- navController.navigate(“second_screen”): 指定したルート名(”second_screen”)に対応するComposable関数に遷移します。
5. GreetingPreview 関数も FirstScreenPreview にリネーム
プレビュー用の関数も変更しておきましょう。
@Preview(showBackground = true)
@Composable
fun FirstScreenPreview() {
YourAppNameTheme {
FirstScreen(navController = rememberNavController(), name = "Android")
}
}
- プレビューでは実際のナビゲーションは発生しないので、rememberNavController() でダミーの NavController を渡しておきます。
これで、アプリを再実行すると、最初の画面に「2番目の画面へ」というボタンが表示され、それを押すと「これは2番目の画面です!」と表示される画面に遷移し、そこから「最初の画面に戻る」ボタンで元の画面に戻れるはずです。
※Google AI Studioによる回答を参考にしました
