Przenieś układ koordynatora do tworzenia wiadomości

CoordinatorLayout to ViewGroup, który umożliwia tworzenie złożonych, nakładających się i zagnieżdżonych układów. Służy jako kontener, który umożliwia określone interakcje Material Design, takie jak rozwijanie i zwijanie pasków narzędzi oraz arkuszy dolnych, w przypadku widoków zawartych w tym kontenerze.

W Compose najbliższym odpowiednikiem znaku CoordinatorLayout jest znak Scaffold. Scaffold udostępnia miejsca na treści, w których można łączyć komponenty Material w typowych wzorcach ekranu i interakcjach. Na tej stronie dowiesz się, jak przenieść implementację CoordinatorLayout, aby używać Scaffold w Compose.

Etapy migracji

Aby przeprowadzić migrację z CoordinatorLayout do Scaffold, wykonaj te czynności:

  1. W poniższym fragmencie kodu element CoordinatorLayout zawiera element AppBarLayout, który z kolei zawiera elementy ToolBar, ViewPager i FloatingActionButton. Usuń z hierarchii interfejsu element CoordinatorLayout i jego elementy podrzędne, a w jego miejsce dodaj element ComposeView.

    ```xml

    <!-- AppBarLayout contents here -->
    

    ```

  2. W fragmencie lub aktywności uzyskaj odwołanie do dodanego właśnie elementu ComposeView i wywołaj na nim metodę setContent. W treści metody ustaw Scaffold jako jej zawartość:

    composeView.setContent {
        Scaffold(Modifier.fillMaxSize()) { contentPadding ->
            // Scaffold contents
            // ...
        }
    }

  3. W treści Scaffold dodaj główną zawartość ekranu. Główna treść w powyższym pliku XML to ViewPager2, więc użyjemy elementu HorizontalPager, który jest jego odpowiednikiem w Compose. content lambda Scaffold otrzymuje też instancję PaddingValues, która powinna zostać zastosowana do głównego elementu treści. Możesz użyć Modifier.padding, aby zastosować ten sam PaddingValues do HorizontalPager.

    composeView.setContent {
        Scaffold(Modifier.fillMaxSize()) { contentPadding ->
            val pagerState = rememberPagerState {
                10
            }
            HorizontalPager(
                state = pagerState,
                modifier = Modifier.padding(contentPadding)
            ) { /* Page contents */ }
        }
    }

  4. Użyj innych miejsc na treści, które udostępnia Scaffold, aby dodać więcej elementów ekranu i przenieść pozostałe widoki podrzędne. W slocie topBar możesz dodać TopAppBar, a w slocie floatingActionButton – FloatingActionButton.

    composeView.setContent {
        Scaffold(
            Modifier.fillMaxSize(),
            topBar = {
                TopAppBar(
                    title = {
                        Text("My App")
                    }
                )
            },
            floatingActionButton = {
                FloatingActionButton(
                    onClick = { /* Handle click */ }
                ) {
                    Icon(
                        Icons.Filled.Add,
                        contentDescription = "Add Button"
                    )
                }
            }
        ) { contentPadding ->
            val pagerState = rememberPagerState {
                10
            }
            HorizontalPager(
                state = pagerState,
                modifier = Modifier.padding(contentPadding)
            ) { /* Page contents */ }
        }
    }

Częste przypadki użycia

Zwijanie i rozwijanie pasków narzędzi

W systemie View do zwijania i rozwijania paska narzędzi za pomocą CoordinatorLayout używasz elementu AppBarLayout jako kontenera paska narzędzi. Następnie możesz określić wartość z zakresu Behavior–layout_behavior w pliku XML powiązanego widoku z możliwością przewijania (np. RecyclerView lub NestedScrollView), aby zadeklarować, jak pasek narzędzi ma się zwijać lub rozwijać podczas przewijania.

W Compose możesz uzyskać podobny efekt za pomocą TopAppBarScrollBehavior. Aby na przykład wdrożyć zwijany/rozwijany pasek narzędzi, który pojawia się podczas przewijania w górę, wykonaj te czynności:

  1. Wywołaj funkcję TopAppBarDefaults.enterAlwaysScrollBehavior(), aby utworzyć TopAppBarScrollBehavior.
  2. Przekaż utworzony TopAppBarScrollBehavior do TopAppBar.
  3. Połącz element NestedScrollConnection za pomocą elementu Modifier.nestedScroll na elemencie Scaffold, aby element Scaffold mógł odbierać zdarzenia przewijania zagnieżdżonego, gdy zawartość możliwa do przewijania jest przewijana w górę lub w dół. Dzięki temu pasek aplikacji może się odpowiednio zwijać i rozwijać podczas przewijania treści.

    // 1. Create the TopAppBarScrollBehavior
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
    
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text("My App")
                },
                // 2. Provide scrollBehavior to TopAppBar
                scrollBehavior = scrollBehavior
            )
        },
        // 3. Connect the scrollBehavior.nestedScrollConnection to the Scaffold
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection)
    ) { contentPadding ->
        /* Contents */
        // ...
    }

Dostosowywanie efektu zwijania/rozwijania podczas przewijania

Możesz podać kilka parametrów dla elementu enterAlwaysScrollBehavior, aby dostosować efekt animacji zwijania/rozwijania. TopAppBarDefaults udostępnia też inne TopAppBarScrollBehavior, takie jak exitUntilCollapsedScrollBehavior, który rozwija pasek aplikacji tylko wtedy, gdy treść jest przewinięta do samego dołu.

Aby utworzyć całkowicie niestandardowy efekt (np. efekt paralaksy), możesz też utworzyć własny NestedScrollConnection i ręcznie przesunąć pasek narzędzi podczas przewijania treści. Przykład kodu znajdziesz w przykładzie zagnieżdżonego przewijania w AOSP.

Szuflady

W przypadku widoków panel nawigacji implementujesz za pomocą elementu DrawerLayout jako widoku głównego. Z kolei CoordinatorLayout jest widokiem dziecka elementu DrawerLayout. Element DrawerLayout zawiera też inny widok podrzędny, np. NavigationView, który wyświetla opcje nawigacji w panelu.

W Compose możesz wdrożyć panel nawigacyjny za pomocą komponentu ModalNavigationDrawer. ModalNavigationDrawer oferuje drawerContent miejsce na szufladę i content miejsce na zawartość ekranu.

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    Scaffold(Modifier.fillMaxSize()) { contentPadding ->
        // Scaffold content
        // ...
    }
}

Więcej informacji znajdziesz w sekcji Szuflady.

Paski powiadomień

Scaffold udostępnia snackbarHost, który może przyjmować SnackbarHost komponenty do wyświetlania Snackbar.

val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
Scaffold(
    snackbarHost = {
        SnackbarHost(hostState = snackbarHostState)
    },
    floatingActionButton = {
        ExtendedFloatingActionButton(
            text = { Text("Show snackbar") },
            icon = { Icon(Icons.Filled.Image, contentDescription = "") },
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar("Snackbar")
                }
            }
        )
    }
) { contentPadding ->
    // Screen content
    // ...
}

Więcej informacji znajdziesz w sekcji Paski z informacjami.

Więcej informacji

Więcej informacji o migracji CoordinatorLayout do Compose znajdziesz w tych materiałach: