iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0

https://ithelp.ithome.com.tw/upload/images/20220912/20151958IFjRs0xIZ4.png Medium 好讀版

Compose 的設計宗旨是支援 Material Design 的原則。許多 UI 元件都按照 Material Design 實作。在本文章中,我們將學習如何使用 Material Design 元件來設定應用程式樣式。

此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 索取兌換碼

使用 Material Design

我們的日記 UI 現在已有排版,但外觀尚有待改善。

Jetpack Compose 原生就有實作 Material Design 及其 UI 元件。我們將會使用 Material Design 來改善 DiaryCard composable 的外觀。

首先,使用我們在專案中建立的 Material theme KimojiThemeSurface 來將 DiaryCard 函式包起來。請務必同時在 @PreviewsetContent 函式中進行同樣操作。如此可確保我們的 composables 可以沿用 app 主題中定義的樣式,進而確保在整個 app 中保持一致。

Material Design 以 ColorTypographyShape 三大元素為建構基礎。 我們需要逐一新增這些元素。

注意:空白 Compose Activity 範本會為專案產生預設主題,以讓我們自訂 MaterialTheme。如果您為專案指定的名稱不是 Kimoji,可以在 ui.theme subpackage 下的 Theme.kt 檔案中找到自訂主題。

// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            KimojiTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    DiaryCard(Diary("Joy", "Hey, take a look at Jetpack Compose, it's great!"))
                }
            }
        }
    }
}

@Preview
@Composable
fun PreviewMessageCard() {
    KimojiTheme {
        Surface {
            DiaryCard(
                diary = Diary("Joy", "Take a look at Jetpack Compose, it's great!")
            )
        }
    }
}

色彩

透過 MaterialTheme.colors 設定主題顏色樣式。我們可以在需要顏色的任意位置使用主題中的這些值。
我們來設定心情文字的樣式,並為 emoji 加上邊框。

// ...
import androidx.compose.foundation.border
import androidx.compose.material.MaterialTheme

@Composable
fun DiaryCard(diary: Diary) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.joy),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
       )

       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = diary.emotion,
               color = MaterialTheme.colors.secondaryVariant
           )

           Spacer(modifier = Modifier.height(4.dp))
           Text(text = diary.notes)
       }
   }
}

字型

MaterialTheme 中提供 Material 字型樣式,只要將這些樣式新增至 Text composables 即可。

// ...

@Composable
fun DiaryCard(diary: Diary) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.joy),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(
                text = diary.emotion,
                color = MaterialTheme.colors.secondaryVariant,
                style = MaterialTheme.typography.subtitle2
            )

            Spacer(modifier = Modifier.height(4.dp))

            Text(
                text = diary.notes,
                style = MaterialTheme.typography.body2
            )
        }
    }
}

形狀

透過 Shape,就可以為我們的日記新增最後的點睛之筆。首先,將筆記文字包在 Surface composable 中。如此即可自訂筆記內文的形狀和高度。此外,還要為筆記文字新增 padding,以美化排版。

// ...
import androidx.compose.material.Surface

@Composable
fun DiaryCard(diary: Diary) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.joy),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(
                text = diary.emotion,
                color = MaterialTheme.colors.secondaryVariant,
                style = MaterialTheme.typography.subtitle2
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(shape = MaterialTheme.shapes.medium, elevation = 1.dp) {
                Text(
                    text = diary.notes,
                    modifier = Modifier.padding(all = 4.dp),
                    style = MaterialTheme.typography.body2
                )
            }
        }
    }
}

套用深色主題

我們可以套用深色主題 (或夜間模式),避免晚上螢幕顯示亮度過強,或單純用來節省裝置電量。Jetpack Compose 預設可以支援 Material Design 深色主題。有套用 Material Design 的顏色、文字都會自動切換自深色主題。
我們可以在檔案中建立多個 preview 函式,或新增多個標籤至相同函式。
我們來新增 preview 標籤並套用夜間模式。

// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewDiaryCard() {
    KimojiTheme {
        Surface {
            DiaryCard(
                diary = Diary("Joy", "Hey, take a look at Jetpack Compose, it's great!")
            )
        }
    }
}

IDE 產生的 Theme.kt 檔案會定義淺色和深色主題的顏色選項。
目前為止,我們已建立一個日記 UI 元件,它可以不同樣式顯示一個 emoji 和兩段文字,並且在淺色和深色主題下都有良好的視覺效果!

此系列文章是以我的業餘專案:Kimoji 為範例。

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 索取兌換碼

Reference: https://developer.android.com/jetpack/compose/tutorial


上一篇
Compose Layouts
下一篇
Compose 清單和動畫
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言