iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Mobile Development

寫Jetpack Compose ,會很有畫面哦!系列 第 14

寫Jetpack Compose ,會很有畫面哦! - Day14 Compose 的版面配置 Part2

  • 分享至 

  • xImage
  •  

Compose 的版面配置 Layouts

Jetpack Compose 可協助您為應用程式輕鬆設計高效率的版面配置。
以下頁面詳細介紹如何設計和實作版面配置:
  • Layout basics 版面配置基本概念:瞭解直觀應用程式 UI 的建構模塊。
  • Material Components and layouts 質感元件和版面配置:瞭解 Compose 的質感元件和版面配置。
  • Custom layouts 自訂版面配置:瞭解如何控管應用程式的版面配置,以及如何設計自己的自訂版面配置。
  • Build adaptive layouts 建立自動調整版面配置:瞭解如何使用 Compose 根據不同螢幕大小、方向和板型規格建構版面配置。
  • Alignment lines 對齊線條:瞭解如何建立自訂對齊線條,以精確對齊並定位 UI 元素。
  • Intrinsic measurements 固有測量尺寸:瞭解如何為 UI 元素設定固有高度或寬度,讓您精確控管元素在版面配置中的編排方式。
  • ConstraintLayout:瞭解如何在 Compose UI 中使用 ConstraintLayout。

Material Components and layouts 質感元件和版面配置

可組合函式使用中結合材質元件 (按鈕、卡片、切換按鈕等) 和版面配置 (例如 Scaffold) ,來讓畫面看來美美的。

使用應用程式中 MaterialTheme 的值提供給材質元件:
可以用按鈕、卡片、switch開關等

@Composable
fun MyApp() {
    MaterialTheme {
        // Material Components like Button, Card, Switch, etc.
    }
}

材質元件內容的位置 Content slots

材質元件通常會提供「槽位」來合內部內容 (文字標籤、圖示等)作結合。

  • 使用 Button ,結合圖片和文字變成美美的按鈕
    以前用ImageButton 元件,就只能有圖,不能有字
@Composable
fun Greeting(name: String) {
        Column() {
        Text(text = "Hello $name!")
        Row() {
            Button(
                onClick = { /* ... */ },
                // Uses ButtonDefaults.ContentPadding by default
                contentPadding = PaddingValues(
                    start = 20.dp,
                    top = 12.dp,
                    end = 20.dp,
                    bottom = 12.dp
                )
            ) {
                // Inner content including an icon and a text label
                Icon(
                    Icons.Filled.Favorite,
                    contentDescription = "Favorite",
                    modifier = Modifier.size(ButtonDefaults.IconSize)
                )
                Spacer(Modifier.size(ButtonDefaults.IconSpacing))
                Text("You")
            }
            ExtendedFloatingActionButton(
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        Icons.Filled.Call,
                        contentDescription = "Favorite"
                    )
                },
                text = { Text("Me") }
            )
        }

    }
}  

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220920/20121643cfRTN4fj8s.png

版面配置 screen patterns

使用Compose 的版面配置可以很便利將材質元件合併成常見的螢幕模式。
  • 使用 Scaffold 為頂部應用欄 Top App Bar
@Composable
fun Greeting(name: String) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "TopAppBar標題")
                },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Filled.Menu, "backIcon")
                    }
                },
                backgroundColor = MaterialTheme.colors.primary,
                contentColor = Color.White,
                elevation = 10.dp
            )
        }, content = {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color(0xff8d6e63)),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "這個是內容頁",
                    fontSize = 30.sp,
                    color = Color.White
                )
            }

        })
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220920/20121643DWoCHSOAoY.png

  • 使用 Scaffold 為底部應用欄 Button App Bar
@Composable
fun Greeting(...) {
//BottomAppBar Sample
    Scaffold(bottomBar = {BottomBar()}
    ) {
        //content area
        Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color(0xff8d6e63)),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "這個是內容頁",
                    fontSize = 30.sp,
                    color = Color.White
                )
            }
    } 
}

//底部按鈕

@Composable
fun BottomBar() {
    val selectedIndex = remember { mutableStateOf(0) }
    BottomNavigation(elevation = 10.dp) {

        BottomNavigationItem(icon = {
            Icon(imageVector = Icons.Default.Home,"")
        },
            label = { Text(text = "Home") },
            selected = (selectedIndex.value == 0),
            onClick = {
                selectedIndex.value = 0
            })

        BottomNavigationItem(icon = {
            Icon(imageVector = Icons.Default.Favorite,"")
        },
            label = { Text(text = "Favorite") },
            selected = (selectedIndex.value == 1),
            onClick = {
                selectedIndex.value = 1
            })

        BottomNavigationItem(icon = {
            Icon(imageVector = Icons.Default.Person,"")
        },
            label = { Text(text = "Profile") },
            selected = (selectedIndex.value == 2),
            onClick = {
                selectedIndex.value = 2
            })
    }
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220920/20121643u01VBUyirK.png

  • 使用 Scaffold 和 懸浮動作按鈕 Floating action buttons
@Composable
fun Greeting(...) {
//floatingActionButton
    Scaffold(
        floatingActionButton = {
            FloatingActionButton(onClick = { /* ... */ }) {
                /* FAB content */
                IconButton(onClick = {}) {
                        Icon(Icons.Filled.Add, "addIcon")
                    }
            }
        },
        // Defaults to false
        isFloatingActionButtonDocked = true,
        bottomBar = {
            BottomAppBar { /* Bottom app bar content */ }
        }
    ) {
        // Screen content
    }
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220920/20121643toT6HRdaPX.png

  • 使用 Scaffold 為側邊欄
@Composable
fun Greeting(...) {
  // 側邊欄
    val scaffoldState = rememberScaffoldState()
    val scope = rememberCoroutineScope()
    Scaffold(
        scaffoldState = scaffoldState,
        drawerContent = {
            // Drawer content
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Green),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "這個是側邊欄",
                    fontSize = 30.sp,
                    color = Color.White
                )
            }
        },
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("側邊欄") },
                onClick = {
                    scope.launch {
                        scaffoldState.drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                },
                icon= { Icon(Icons.Filled.Menu, "addIcon") }
            )
        }
    ) {
        // Screen content
        Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color(0xff8d6e63)),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "這個是內容頁",
                    fontSize = 30.sp,
                    color = Color.White
                )
            }
    }
}

顯示結果
close
https://ithelp.ithome.com.tw/upload/images/20220920/20121643Ss1udlPasx.png

open
https://ithelp.ithome.com.tw/upload/images/20220920/20121643gYidmaQb0k.png

參考:

https://developer.android.com/jetpack/compose/layouts/material
https://www.jetpackcompose.net/scaffold


上一篇
寫Jetpack Compose ,會很有畫面哦! - Day13 Compose 的版面配置 Layouts
下一篇
寫Jetpack Compose ,會很有畫面哦! - Day15 Compose 的版面配置 part3
系列文
寫Jetpack Compose ,會很有畫面哦!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言