メモ > 技術 > IDE: AndroidStudio > アプリの作成(Jetpack Compose / 一覧と詳細)
アプリの作成(Jetpack Compose / 一覧と詳細)
Jetpack Compose入門 アプリを作る知識-2(一覧から詳細への画面遷移~rememberNavControllerなど)
https://zenn.dev/ko2ic/articles/f00dbfd350d521
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HelloWorldTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainScreen()
}
}
}
}
}
@Composable
fun MainScreen() {
val mocks = (1..100).map {
Pair("リストのタイトル$it", "これはリストのメッセージ${it}です。")
}
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "ListScreen") {
composable("ListScreen") {
ListScreen(
mocks,
onNavigateToDetailScreen = { title, body -> navController.navigate("DetailScreen/$title/$body") }
)
}
composable(
"DetailScreen/{title}/{body}",
arguments = listOf(
navArgument("title") { type = NavType.StringType },
navArgument("body") { type = NavType.StringType }
)
) { backStackEntry ->
val title = backStackEntry.arguments?.getString("title") ?: ""
val body = backStackEntry.arguments?.getString("body") ?: ""
DetailScreen(
title,
body,
onNavigateToFirstScreen = { navController.navigateUp() }
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ListScreen(contents: List<Pair<String, String>>, onNavigateToDetailScreen: (String, String) -> Unit) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("リストのサンプル") }
)
}
) { innerPadding ->
val context = LocalContext.current
ConstraintLayout(
modifier = Modifier.padding(innerPadding)
) {
LazyColumn {
items(contents.size) { index ->
val content = contents[index]
ListTitle(title = content.first, body = content.second)
{
onNavigateToDetailScreen(content.first, content.second)
}
}
}
}
}
}
@Composable
private fun ListTitle(
title: String,
body: String,
onClick: () -> Unit
) {
Surface(
modifier = Modifier.clickable { onClick() },
shape = MaterialTheme.shapes.medium
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(all = 8.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 16.dp),
) {
Text(title)
Spacer(modifier = Modifier.height(4.dp))
Text(body)
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun DetailScreen(
title: String,
body: String,
onNavigateToFirstScreen: () -> Unit
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("詳細") },
navigationIcon = {
IconButton(onClick = onNavigateToFirstScreen) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "戻る"
)
}
}
)
}
) { innerPadding ->
ConstraintLayout(
modifier = Modifier.padding(innerPadding),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 16.dp),
) {
Text("これは詳細画面です。")
Text("タイトル: ${title}")
Text("本文: ${body}")
}
}
}
}