💨

Jetpack ComposeのScaffoldを試してみた

2023/09/28に公開

はじめに

Scaffoldを使うと一般的なレイアウトが簡単に(?)構成できるということで
Scaffoldを使ってTopAppBarとBottomAppBarを試してみました。

早速作ってみる

色々と調べたりして、書いたコードがこちら。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()
            Scaffold(
                topBar = {
                    TopAppBar(
                        title = {
                            Box() { Text( text = "TopAppBar" ) }
                        },
                        colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.LightGray)
                    )
                },
                bottomBar = {
                    BottomAppBar(
                        containerColor = Color.LightGray
                    ) {
                        MyBottomNav(navController = navController)
                    }
                }
            ) { padding ->
                ScreenNavigation(navController = navController, padding = padding)
            }
        }
    }

    @Composable
    fun ScreenNavigation(
        navController: NavHostController,
        padding: PaddingValues
    ){
        NavHost(
            navController = navController,
            startDestination = "home"
        ){
            composable("home"){
                Screen1(padding)
            }
            composable("setting"){
                Screen2(padding)
            }
        }
    }

    @Composable
    fun MyBottomNav(
        navController: NavHostController
    ) {
        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentDestination = navBackStackEntry?.destination

        BottomNavigation(
            modifier = Modifier
                .padding(0.dp, 0.dp, 0.dp, 5.dp)
                .height(100.dp)
        ) {
            BottomNavigationItem(
                icon = {
                    Icon(
                        imageVector = Icons.Filled.Home,
                        contentDescription = ""
                    )
                },
                selected = currentDestination?.hierarchy?.any {
                    it.route == "home"
                } == true,
                onClick = {
                    navController.navigate("home")
                },
                label = { Text(text = "ホーム")}
            )
            BottomNavigationItem(
                icon = {
                    Icon(
                        imageVector = Icons.Filled.Settings,
                        contentDescription = ""
                    )
                },
                selected = currentDestination?.hierarchy?.any {
                    it.route == "setting"
                } == true,
                onClick = {
                    navController.navigate("setting")
                },
                label = { Text(text = "設定")}
            )
        }
    }

    @Composable
    fun Screen1(padding: PaddingValues) {
        Text(text = "ホーム", modifier = Modifier.padding(padding))
    }

    @Composable
    fun Screen2(padding: PaddingValues) {
        Text(text = "設定", modifier = Modifier.padding(padding))
    }
}

動かしてみると・・・?

実行するとBottomAppBarが素敵な色に。

問題箇所

ここが想定通りになっていない。

BottomAppBar(
    containerColor = Color.LightGray
)

修正方法

BottomAppBarで色指定するのではなく
BottomNavigationで色指定してあげる。

BottomNavigation(
    modifier = Modifier
        .padding(0.dp, 0.dp, 0.dp, 5.dp)
        .height(100.dp),
+   backgroundColor = Color.LightGray
)

完成画面

上下にバー、真ん中はnavControllerで画面を制御してるので
下のバーのボタンを押すと画面切り替えができます。
(静止画なので動きません)

まとめ

最初のものも適用されていない訳ではなく、見にくいですが裏でしっかりと変わっています。
色に限らず一番手前に表示されているもののレイアウトをいじりたいなら
それを作ってるところでちゃんと指定してあげようね
というお話でした。

補足

API29以上で作ってるならLayout inspectorで見るとどこがおかしいかわかりやすいです。

参考

https://qiita.com/Ryosuke-Android/items/2a94d4fed2586c0ed31c
https://www.gesource.jp/weblog/?p=8591

コラボスタイル Developers

Discussion