今回実装するもの
今回は一つ前の画面に戻るためのボタンを実装します。
前回の記事で観光地リストを表示するアプリに詳細画面を追加したのですが、その時に戻るボタンの実装を忘れて随分と不親切なアプリになってしまい、その反省として今回戻るボタンを追加します。
Before | After |
---|---|
前回の記事
詳細画面に画面遷移する機能の実装をしたときの記事です。
ベースとなるプログラム
かねてより制作している観光地リストを表示させるリストに戻るボタンを追加します。
実装する画面
戻るボタンは観光地の詳細を開いたときだけ出現するようにします。
リスト画面 | 詳細画面 |
---|---|
戻るボタンは Toolbar という画面上部に表示されるエリアへ設置し、クリックした時に画面が戻る機能を持たせます。
Toolbar はアプリタイトルが中央に配置される、CenterAlignedTopAppBar
を使用します。これを使えば戻るボタンを削除した時にタイトルがずれてしまう問題を解決できます。本音は、左寄りにさせた方がかっこいいかなと思いつつ、状況が変わっても簡単に対応できるよう実装したいというのがあります。
他の種類を使いたい方は Android Developers のページに記載されていますのでお試しください。
- LandmarkDetail.kt
- 観光地情報詳細画面
- LandmarkList.kt
- 観光地リスト画面
詳細画面での実装コード
navController を忘れずに
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LandmarkDetailView(landmarkId: Int,landmarkName: String,description:String,airport:String,navController: NavController) {
CenterAlignedTopAppBar(
title = {Text(text = stringResource(id = R.string.app_name), maxLines = 1, overflow = TextOverflow.Ellipsis)},
// 「←」アイコンを設定
navigationIcon = {
IconButton(onClick = { navController.popBackStack() }) {
Icon(Icons.Default.ArrowBack, contentDescription = "Back")
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary
)
)
}
リストでの実装コード
ここではアイコンのコードを削除して不要な表示をしないようにします。
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LandmarkList(viewModel: LandmarkViewModel,navController: NavController) {
CenterAlignedTopAppBar(
title = {Text(text = stringResource(id = R.string.app_name), maxLines = 1, overflow = TextOverflow.Ellipsis)},
// Icon のコードを削除
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary
)
)
}
NavHost の実装コード
val navController = rememberNavController()
SetLandmarkView(LandmarkViewModel,navController = navController)
@Composable
fun SetLandmarkView(landmarkViewModel: LandmarkViewModel,navController: NavHostController){
NavHost(navController = navController, startDestination = Screen.LANDMARKS.name) {
composable(Screen.LANDMARKS.name) {
LandmarkList(viewModel = landmarkViewModel,navController)
}
composable("${Screen.LANDMARK_DETAIL.name}/{landmarkId}/{landmarkName}/{description}/{airport}",
arguments = listOf(
navArgument("landmarkId") {type = NavType.IntType},
navArgument("landmarkName") {type = NavType.StringType},
navArgument("description"){type = NavType.StringType},
navArgument("airport"){type = NavType.StringType},
)
)
{ backStackEntry ->
val landmarkId = backStackEntry.arguments?.getInt("landmarkId") ?: 0
val landmarkName = backStackEntry.arguments?.getString("landmarkName") ?: ""
val description = backStackEntry.arguments?.getString("description") ?: ""
val airport = backStackEntry.arguments?.getString("airport") ?: ""
// ここで navController を引数とする ( navArgument には記述不要)
LandmarkDetailView(
landmarkId=landmarkId,
landmarkName=landmarkName,
description=description,
airport=airport,
navController = navController
)
}
}
}
以上の実装により戻るボタンの実装は完了です。
Github差分
今回の実装の差分のまとめを Github リンクとして貼っておきます。是非ともご覧ください。
終わりに
戻るボタンは画面上にあると、ユーザーにとってわかりやすくなるため是非とも設置しましょう!