Bermigrasi dari Material 2 ke Material 3 di Compose

Desain Material 3 adalah evolusi berikutnya dari Desain Material. Desain Material ini mencakup versi terbaru tema, komponen, dan fitur personalisasi Material You seperti warna dinamis. Ini adalah update dari Desain Material 2 dan terkait erat dengan gaya visual dan UI sistem baru di Android 12 dan yang lebih baru.

Panduan ini berfokus pada migrasi dari library Jetpack Compose Material (androidx.compose.material) ke library Jetpack Compose Material 3 (androidx.compose.material3).

Pendekatan

Secara umum, Anda tidak boleh menggunakan M2 dan M3 dalam satu aplikasi jangka panjang. Hal ini karena kedua sistem desain dan library masing-masing sangat berbeda dalam hal desain UX/UI dan implementasi Compose-nya.

Aplikasi Anda mungkin menggunakan sistem desain, seperti yang dibuat menggunakan Figma. Jika demikian, kami sangat menyarankan Anda atau tim desain Anda untuk memigrasikannya dari M2 ke M3 sebelum memulai migrasi Compose. Sangat tidak umum jika migrasi aplikasi ke M3 saat desain UX/UI-nya didasarkan pada M2.

Selain itu, pendekatan Anda terhadap migrasi harus berbeda bergantung pada ukuran, kompleksitas, dan desain UX/UI aplikasi. Dengan begitu, Anda dapat meminimalkan dampak terhadap codebase. Anda harus menggunakan pendekatan bertahap untuk migrasi.

Waktu bermigrasi

Anda harus memulai migrasi sesegera mungkin. Namun, penting untuk mempertimbangkan apakah aplikasi Anda berada di posisi realistis untuk sepenuhnya bermigrasi dari M2 ke M3. Ada beberapa skenario pemblokir yang perlu dipertimbangkan sebelum memulai:

Skenario Pendekatan yang direkomendasikan
Tidak ada pemblokir Mulai migrasi bertahap
Komponen dari M2 belum tersedia di M3. Lihat bagian Komponen dan tata letak di bawah. Mulai migrasi bertahap
Anda atau tim desain Anda belum memigrasikan sistem desain aplikasi dari M2 ke M3 Migrasikan sistem desain dari M2 ke M3, lalu mulai migrasi bertahap

Meskipun terpengaruh oleh skenario di atas, Anda harus melakukan pendekatan bertahap untuk migrasi sebelum melakukan dan merilis update aplikasi. Dalam hal ini, Anda akan menggunakan M2 dan M3 secara berdampingan, dan secara bertahap menghentikan M2 saat bermigrasi ke M3.

Pendekatan bertahap

Langkah-langkah umum untuk migrasi bertahap adalah sebagai berikut:

  1. Tambahkan dependensi M3 bersama dependensi M2.
  2. Tambahkan versi M3 tema aplikasi Anda bersama versi M2 tema aplikasi.
  3. Migrasikan setiap modul, layar, atau composable ke M3, bergantung pada ukuran dan kompleksitas aplikasi Anda (lihat bagian di bawah untuk detailnya).
  4. Setelah dimigrasikan sepenuhnya, hapus versi M2 tema aplikasi Anda.
  5. Hapus dependensi M2.

Dependensi

M3 memiliki paket dan versi terpisah untuk M2:

M2

implementation "androidx.compose.material:material:$m2-version"

M3

implementation "androidx.compose.material3:material3:$m3-version"

Lihat versi M3 terbaru di halaman rilis Compose Material 3.

Dependensi Material lainnya di luar library M2 dan M3 utama tidak berubah. Dependensi tersebut menggunakan kombinasi paket dan versi M2 dan M3, tetapi hal ini tidak memengaruhi migrasi. Dependensi dapat digunakan begitu saja dengan M3:

Library Paket dan versi
Compose Material Icons androidx.compose.material:material-icons-*:$m2-version
Compose Material Ripple androidx.compose.material:material-ripple:$m2-version

API Eksperimental

Beberapa API M3 dianggap eksperimental. Dalam hal ini, Anda harus memilih untuk mengaktifkan fungsi atau level file menggunakan anotasi ExperimentalMaterial3Api:

import androidx.compose.material3.ExperimentalMaterial3Api

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
    // M3 composables
}

Tema

Pada M2 dan M3, composable tema diberi nama MaterialTheme, tetapi paket dan parameter impornya berbeda:

M2

import androidx.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M2 content
}

M3

import androidx.compose.material3.MaterialTheme

MaterialTheme(
    colorScheme = AppColorScheme,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M3 content
}

Warna

Perbandingan sistem warna M2 dengan M3
Gambar 1. Sistem warna M2 (kiri) versus sistem warna M3 (kanan).

Sistem warna di M3 sangat berbeda dengan M2. Jumlah parameter warna telah meningkat, memiliki nama berbeda, dan memetakan secara berbeda ke komponen M3. Di Compose, ini berlaku untuk class Colors M2, class ColorScheme M3, dan fungsi terkait:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors

val AppLightColors = lightColors(
    // M2 light Color parameters
)
val AppDarkColors = darkColors(
    // M2 dark Color parameters
)
val AppColors = if (darkTheme) {
    AppDarkColors
} else {
    AppLightColors
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme

val AppLightColorScheme = lightColorScheme(
    // M3 light Color parameters
)
val AppDarkColorScheme = darkColorScheme(
    // M3 dark Color parameters
)
val AppColorScheme = if (darkTheme) {
    AppDarkColorScheme
} else {
    AppLightColorScheme
}

Mengingat perbedaan yang signifikan antara sistem warna M2 dan M3, tidak ada pemetaan yang wajar untuk parameter Color. Sebagai gantinya, gunakan alat Builder Tema Material untuk membuat skema warna M3. Gunakan warna M2 sebagai warna sumber inti pada alat, yang diperluas alat ini ke palet warna yang digunakan oleh skema warna M3. Pemetaan berikut direkomendasikan sebagai titik awal:

M2 Material Theme Builder
primary Primer
primaryVariant Sekunder
secondary Tersier
surface atau background Netral
Warna M2 yang digunakan di Material Theme Builder untuk membuat skema warna M3
Gambar 2. Warna M2 Jetchat yang digunakan di Material Theme Builder untuk membuat skema warna M3.

Anda dapat menyalin nilai kode heksadesimal warna untuk tema terang dan gelap dari alat ini dan menggunakannya untuk menerapkan instance ColorScheme M3. Atau, Material Theme Builder dapat mengekspor kode Compose.

isLight

Tidak seperti class Colors M2, class ColorScheme M3 tidak menyertakan parameter isLight. Secara umum, Anda harus mencoba membuat model apa pun yang memerlukan informasi ini di level tema. Contoh:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
import androidx.compose.material.MaterialTheme

@Composable
private fun AppTheme(
  darkTheme: Boolean = isSystemInDarkTheme(),
  content: @Composable () -> Unit
) {
  val colors = if (darkTheme) darkColors(…) else lightColors(…)
  MaterialTheme(
      colors = colors,
      content = content
  )
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = if (MaterialTheme.colors.isLight) 0.dp else 4.dp
        …
    }
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.MaterialTheme

val LocalCardElevation = staticCompositionLocalOf { Dp.Unspecified }
@Composable
private fun AppTheme(
   darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
   val cardElevation = if (darkTheme) 4.dp else 0.dp
    CompositionLocalProvider(LocalCardElevation provides cardElevation) {
        val colorScheme = if (darkTheme) darkColorScheme(…) else lightColorScheme(…)
        MaterialTheme(
            colorScheme = colorScheme,
            content = content
        )
    }
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = LocalCardElevation.current
        …
    }
}

Lihat panduan Sistem desain kustom di Compose untuk informasi selengkapnya.

Warna dinamis

Fitur baru di M3 adalah warna dinamis. Daripada menggunakan warna kustom, ColorScheme M3 dapat menggunakan warna wallpaper perangkat di Android 12 dan yang lebih baru, menggunakan fungsi berikut:

Tipografi

Perbandingan sistem tipografi M2 dan M3
Gambar 3. Sistem tipografi M3 (kiri) versus sistem tipografi M2 (kanan)

Sistem tipografi di M3 berbeda dengan M2. Jumlah parameter tipografi kurang lebih sama, tetapi memiliki nama dan pemetaan yang berbeda untuk komponen M3. Di Compose, ini berlaku untuk class Typography M2 dan class Typography M3:

M2

import androidx.compose.material.Typography

val AppTypography = Typography(
    // M2 TextStyle parameters
)

M3

import androidx.compose.material3.Typography

val AppTypography = Typography(
    // M3 TextStyle parameters
)

Pemetaan parameter TextStyle berikut direkomendasikan sebagai titik awal:

M2 M3
h1 displayLarge
h2 displayMedium
h3 displaySmall
T/A headlineLarge
h4 headlineMedium
h5 headlineSmall
h6 titleLarge
subtitle1 titleMedium
subtitle2 titleSmall
body1 bodyLarge
body2 bodyMedium
caption bodySmall
button labelLarge
T/A labelMedium
overline labelSmall

Bentuk

Perbandingan sistem bentuk M2 dan M3
Gambar 4. Sistem bentuk M2 (kiri) vs. sistem bentuk M3 (kanan)

Sistem bentuk di M3 berbeda dengan M2. Jumlah parameter bentuk telah meningkat, diberi nama berbeda dan dipetakan berbeda ke komponen M3. Di Compose, ini berlaku untuk class Shapes M2 dan class Shapes M3:

M2

import androidx.compose.material.Shapes

val AppShapes = Shapes(
    // M2 Shape parameters
)

M3

import androidx.compose.material3.Shapes

val AppShapes = Shapes(
    // M3 Shape parameters
)

Pemetaan parameter Shape berikut direkomendasikan sebagai titik awal:

M2 M3
T/A extraSmall
small small
medium medium
large large
T/A extraLarge

Komponen dan tata letak

Sebagian besar komponen dan tata letak dari M2 tersedia di M3. Namun, ada beberapa yang hilang serta yang baru dan tidak ada di M2. Selain itu, beberapa komponen M3 memiliki lebih banyak variasi dibandingkan dengan yang setara di M2. Secara umum, antarmuka API M3 berupaya semirip mungkin dengan persamaan terdekatnya di M2.

Dengan sistem warna, tipografi, dan bentuk terbaru, komponen M3 cenderung dipetakan secara berbeda ke nilai tema baru. Sebaiknya lihat direktori token di kode sumber Compose Material 3 sebagai sumber kebenaran untuk pemetaan ini.

Meskipun beberapa komponen memerlukan pertimbangan khusus, pemetaan fungsi berikut direkomendasikan sebagai titik awal:

API tidak ada:

M2 M3
androidx.compose.material.swipeable Belum tersedia

API yang diganti:

M2 M3
androidx.compose.material.BackdropScaffold Tidak ada M3 yang setara, migrasikan ke Scaffold atau BottomSheetScaffold
androidx.compose.material.BottomDrawer Tidak ada M3 yang setara, migrasikan ke ModalBottomSheet

API yang berganti nama:

M2 M3
androidx.compose.material.BottomNavigation androidx.compose.material3.NavigationBar
androidx.compose.material.BottomNavigationItem androidx.compose.material3.NavigationBarItem
androidx.compose.material.Chip androidx.compose.material3.AssistChip atau androidx.compose.material3.SuggestionChip
androidx.compose.material.ModalBottomSheetLayout androidx.compose.material3.ModalBottomSheet
androidx.compose.material.ModalDrawer androidx.compose.material3.ModalNavigationDrawer

Semua API lainnya:

M2 M3
androidx.compose.material.AlertDialog androidx.compose.material3.AlertDialog
androidx.compose.material.Badge androidx.compose.material3.Badge
androidx.compose.material.BadgedBox androidx.compose.material3.BadgedBox
androidx.compose.material.BottomAppBar androidx.compose.material3.BottomAppBar
androidx.compose.material.BottomSheetScaffold androidx.compose.material3.BottomSheetScaffold
androidx.compose.material.Button androidx.compose.material3.Button
androidx.compose.material.Card androidx.compose.material3.Card
androidx.compose.material.Checkbox androidx.compose.material3.Checkbox
androidx.compose.material.CircularProgressIndicator androidx.compose.material3.CircularProgressIndicator
androidx.compose.material.Divider androidx.compose.material3.Divider
androidx.compose.material.DropdownMenu androidx.compose.material3.DropdownMenu
androidx.compose.material.DropdownMenuItem androidx.compose.material3.DropdownMenuItem
androidx.compose.material.ExposedDropdownMenuBox androidx.compose.material3.ExposedDropdownMenuBox
androidx.compose.material.ExtendedFloatingActionButton androidx.compose.material3.ExtendedFloatingActionButton
androidx.compose.material.FilterChip androidx.compose.material3.FilterChip
androidx.compose.material.FloatingActionButton androidx.compose.material3.FloatingActionButton
androidx.compose.material.Icon androidx.compose.material3.Icon
androidx.compose.material.IconButton androidx.compose.material3.IconButton
androidx.compose.material.IconToggleButton androidx.compose.material3.IconToggleButton
androidx.compose.material.LeadingIconTab androidx.compose.material3.LeadingIconTab
androidx.compose.material.LinearProgressIndicator androidx.compose.material3.LinearProgressIndicator
androidx.compose.material.ListItem androidx.compose.material3.ListItem
androidx.compose.material.NavigationRail androidx.compose.material3.NavigationRail
androidx.compose.material.NavigationRailItem androidx.compose.material3.NavigationRailItem
androidx.compose.material.OutlinedButton androidx.compose.material3.OutlinedButton
androidx.compose.material.OutlinedTextField androidx.compose.material3.OutlinedTextField
androidx.compose.material.RadioButton androidx.compose.material3.RadioButton
androidx.compose.material.RangeSlider androidx.compose.material3.RangeSlider
androidx.compose.material.Scaffold androidx.compose.material3.Scaffold
androidx.compose.material.ScrollableTabRow androidx.compose.material3.ScrollableTabRow
androidx.compose.material.Slider androidx.compose.material3.Slider
androidx.compose.material.Snackbar androidx.compose.material3.Snackbar
androidx.compose.material.Switch androidx.compose.material3.Switch
androidx.compose.material.Tab androidx.compose.material3.Tab
androidx.compose.material.TabRow androidx.compose.material3.TabRow
androidx.compose.material.Text androidx.compose.material3.Text
androidx.compose.material.TextButton androidx.compose.material3.TextButton
androidx.compose.material.TextField androidx.compose.material3.TextField
androidx.compose.material.TopAppBar androidx.compose.material3.TopAppBar
androidx.compose.material.TriStateCheckbox androidx.compose.material3.TriStateCheckbox

Lihat komponen dan tata letak M3 terbaru di ringkasan Referensi API Compose Material 3, dan pantau terus halaman rilis untuk API baru dan yang diupdate.

Scaffold, snackbar, dan panel navigasi

Perbandingan scaffold M2 dan M3 dengan snackbar dan panel navigasi
Gambar 5. Scaffold M2 dengan snackbar dan panel navigasi (kiri) versus scaffold M3 dengan snackbar dan panel navigasi (kanan).

Scaffold di M3 berbeda dengan M2. Pada M2 dan M3, composable tata letak utama bernama Scaffold, tetapi paket dan parameter impor berbeda:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

Scaffold M2 yang berisi parameter backgroundColor kini diberi nama containerColor di Scaffold M3:

M2

import androidx.compose.material.Scaffold

Scaffold(
    backgroundColor = …,
    content = { … }
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    containerColor = …,
    content = { … }
)

Class ScaffoldState M2 tidak ada lagi di M3 karena berisi parameter drawerState yang tidak diperlukan lagi. Untuk menampilkan snackbar dengan Scaffold M3, gunakan SnackbarHostState:

M2

import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    content = {
        …
        scope.launch {
            scaffoldState.snackbarHostState.showSnackbar(…)
        }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = {
        …
        scope.launch {
            snackbarHostState.showSnackbar(…)
        }
    }
)

Semua parameter drawer* dari Scaffold M2 telah dihapus dari Scaffold M3. Hal ini mencakup parameter seperti drawerShape dan drawerContent. Untuk menampilkan panel samping dengan Scaffold M3, gunakan composable panel navigasi, seperti ModalNavigationDrawer, sebagai gantinya:

M2

import androidx.compose.material.DrawerValue
import
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState(
    drawerState = rememberDrawerState(DrawerValue.Closed)
)
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    drawerContent = { … },
    drawerGesturesEnabled = …,
    drawerShape = …,
    drawerElevation = …,
    drawerBackgroundColor = …,
    drawerContentColor = …,
    drawerScrimColor = …,
    content = {
        …
        scope.launch {
            scaffoldState.drawerState.open()
        }
    }
)

M3

import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet(
            drawerShape = …,
            drawerTonalElevation = …,
            drawerContainerColor = …,
            drawerContentColor = …,
            content = { … }
        )
    },
    gesturesEnabled = …,
    scrimColor = …,
    content = {
        Scaffold(
            content = {
                …
                scope.launch {
                    drawerState.open()
                }
            }
        )
    }
)

Panel aplikasi atas

Perbandingan scaffold M2 dan M3 dengan panel aplikasi atas dan daftar yang di-scroll
Gambar 6. Scaffold M2 dengan panel aplikasi atas dan daftar yang di-scroll (kiri) versus scaffold M3 dengan panel aplikasi atas dan daftar yang di-scroll (kanan)

Panel aplikasi atas di M3 berbeda dengan yang ada di M2. Dalam M2 dan M3, composable panel aplikasi atas utama diberi nama TopAppBar, tetapi paket dan parameter impornya berbeda:

M2

import androidx.compose.material.TopAppBar

TopAppBar(…)

M3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

Sebaiknya gunakan CenterAlignedTopAppBar M3 jika sebelumnya Anda meletakkan konten di tengah-tengah TopAppBar M2. Sebaiknya Anda juga mengetahui MediumTopAppBar dan LargeTopAppBar.

Panel aplikasi atas M3 berisi parameter scrollBehavior baru untuk memberikan fungsi yang berbeda saat men-scroll melalui class TopAppBarScrollBehavior, seperti perubahan elevasi. Hal ini berfungsi bersama dengan konten scroll melalui Modifer.nestedScroll. Hal ini dapat dilakukan dalam TopAppBar M2 dengan mengubah parameter elevation secara manual:

M2

import androidx.compose.material.AppBarDefaults
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar

val state = rememberLazyListState()
val isAtTop by remember {
    derivedStateOf {
        state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
    }
}

Scaffold(
    topBar = {
        TopAppBar(
            elevation = if (isAtTop) {
                0.dp
            } else {
                AppBarDefaults.TopAppBarElevation
            },
            …
        )
    },
    content = {
        LazyColumn(state = state) { … }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()

Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            …
        )
    },
    content = {
        LazyColumn { … }
    }
)

Navigasi bawah/Menu navigasi

Perbandingan navigasi bawah M2 dan menu navigasi M3
Gambar 7. Navigasi bawah M2 (kiri) versus menu navigasi M3 (kanan).

Navigasi bawah di M2 telah diganti namanya menjadi menu navigasi di M3. Di M2 terdapat composable BottomNavigation dan BottomNavigationItem, sedangkan di M3 terdapat composable NavigationBar dan NavigationBarItem:

M2

import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem

BottomNavigation {
    BottomNavigationItem(…)
    BottomNavigationItem(…)
    BottomNavigationItem(…)
}

M3

import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem

NavigationBar {
    NavigationBarItem(…)
    NavigationBarItem(…)
    NavigationBarItem(…)
}

Tombol, tombol ikon, dan FAB

Perbandingan tombol M2 dan M3
Gambar 8. Tombol M2 (kiri) versus tombol M3 (kanan)

Tombol, tombol ikon, dan tombol tindakan mengambang (FAB) di M3 berbeda dengan yang ada di M2. M3 mencakup semua composable tombol M2:

M2

import androidx.compose.material.Button
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.IconButton
import androidx.compose.material.IconToggleButton
import androidx.compose.material.OutlinedButton
import androidx.compose.material.TextButton

// M2 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M2 icon buttons
IconButton(…)
IconToggleButton(…)
// M2 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3

import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.TextButton

// M3 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M3 icon buttons
IconButton(…)
IconToggleButton(…)
// M3 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3 juga menyertakan variasi tombol baru. Lihat di ringkasan Referensi API Compose Material 3.

Tombol alih

Perbandingan tombol alih M2 dan M3
Gambar 9. Tombol alih M2 (kiri) versus tombol alih M3 (kanan).

Tombol alih di M3 berbeda dengan M2. Pada M2 dan M3, composable tombol alih diberi nama Switch, tetapi paket impornya berbeda:

M2

import androidx.compose.material.Switch

Switch(…)

M3

import androidx.compose.material3.Switch

Switch(…)

Permukaan dan elevasi

Perbandingan elevasi permukaan M2 dan elevasi permukaan M3 dalam tema terang dan gelap
Gambar 10. Elevasi permukaan M2 versus elevasi permukaan M3 dalam tema terang (kiri) dan tema gelap (kanan).

Sistem permukaan dan elevasi di M3 berbeda dengan M2. Ada dua jenis elevasi di M3:

  • Elevasi bayangan (menambahkan bayangan, sama seperti di M2)
  • Elevasi warna (mengubah warnanya, baru di M3)

Di Compose, ini berlaku untuk fungsi Surface M2 dan fungsi Surface M3:

M2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = …,
    tonalElevation = …
) { … }

Anda dapat menggunakan nilai Dp elevation di M2 untuk shadowElevation dan/atau tonalElevation di M3, bergantung pada preferensi desain UX/UI. Surface adalah composable pendukung di balik sebagian besar komponen, sehingga composable komponen juga dapat menampilkan parameter elevasi yang harus Anda migrasikan dengan cara yang sama.

Elevasi warna di M3 menggantikan konsep overlay elevasi di tema gelap M2. Akibatnya, ElevationOverlay dan LocalElevationOverlay tidak ada di M3, dan LocalAbsoluteElevation di M2 telah diubah menjadi LocalAbsoluteTonalElevation di M3.

Penekanan dan alfa konten

Perbandingan penekanan teks dan ikon di M2 dan M3
Gambar 11. Penekanan teks dan ikon M2 (kiri) versus penekanan teks dan ikon M3 (kanan)

Penekanan di M3 berbeda secara signifikan dengan M2. Di M2, penekanan melibatkan penggunaan warna aktif dengan nilai alfa tertentu untuk membedakan konten seperti teks dan ikon. Di M3, kini ada beberapa pendekatan yang berbeda:

  • Menggunakan warna aktif beserta warna varian aktif dari sistem warna M3 yang diperluas.
  • Penggunaan ketebalan font yang berbeda untuk teks.

Akibatnya, ContentAlpha dan LocalContentAlpha tidak ada di M3 dan harus diganti.

Pemetaan berikut direkomendasikan sebagai titik awal:

M2 M3
onSurface dengan ContentAlpha.high onSurface secara umum, FontWeight.Medium - FontWeight.Black untuk teks
onSurface dengan ContentAlpha.medium onSurfaceVariant secara umum, FontWeight.Thin - FontWeight.Normal untuk teks
onSurface dengan ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

Berikut adalah contoh penekanan ikon di M2 vs. M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Icon(…)
}

Berikut adalah contoh penekanan teks di M2 dan M3:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Text(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Text(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
Text(
    …,
    fontWeight = FontWeight.Bold
)
// Medium emphasis
Text(
    …,
    fontWeight = FontWeight.Normal
)
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Text(
        …,
        fontWeight = FontWeight.Normal
    )
}

Latar belakang dan penampung

Latar belakang di M2 diberi nama penampung di M3. Secara umum, Anda dapat mengganti parameter background* di M2 dengan container* di M3, menggunakan nilai yang sama. Contoh:

M2

Badge(
    backgroundColor = MaterialTheme.colors.primary
) { … }

M3

Badge(
    containerColor = MaterialTheme.colorScheme.primary
) { … }

Untuk mempelajari migrasi dari M2 ke M3 di Compose lebih lanjut, lihat referensi tambahan berikut.

Dokumen

Aplikasi contoh

Video

Referensi API dan kode sumber