Przenieś układ koordynatora do tworzenia wiadomości

CoordinatorLayout to ViewGroup, który umożliwia korzystanie ze złożonych, nakładających się układy zagnieżdżone. Jest on używany jako kontener, który umożliwia określone interakcje w ramach Materiałowego Designu, takie jak rozwijanie i zwijanie pasków narzędzi i elementów dolnych w widokach.

W funkcji Compose najbliższy odpowiednik klasy CoordinatorLayout to Scaffold Scaffold udostępnia przedziały na treści do łączenia elementów Material elementów składowych typowych wzorców ekranów i interakcji; Na tej stronie opisaliśmy, jak przenieść implementację CoordinatorLayout, aby używać Scaffold w Compose.

Etapy migracji

Aby przenieść usługę CoordinatorLayout do Scaffold, wykonaj te czynności:

  1. We fragmencie kodu poniżej sekcja CoordinatorLayout zawiera element AppBarLayout w przypadku: zawierające ToolBar, ViewPager i FloatingActionButton. Skomentuj element CoordinatorLayout i jego podrzędne elementy w hierarchii interfejsu użytkownika, a na ich miejsce dodaj element ComposeView.

    <!--  <androidx.coordinatorlayout.widget.CoordinatorLayout-->
    <!--      android:id="@+id/coordinator_layout"-->
    <!--      android:layout_width="match_parent"-->
    <!--      android:layout_height="match_parent"-->
    <!--      android:fitsSystemWindows="true">-->
    
    <!--    <androidx.compose.ui.platform.ComposeView-->
    <!--        android:id="@+id/compose_view"-->
    <!--        android:layout_width="match_parent"-->
    <!--        android:layout_height="match_parent"-->
    <!--        app:layout_behavior="@string/appbar_scrolling_view_behavior" />-->
    
    <!--    <com.google.android.material.appbar.AppBarLayout-->
    <!--        android:id="@+id/app_bar_layout"-->
    <!--        android:layout_width="match_parent"-->
    <!--        android:layout_height="wrap_content"-->
    <!--        android:fitsSystemWindows="true"-->
    <!--        android:theme="@style/Theme.Sunflower.AppBarOverlay">-->
    
        <!-- AppBarLayout contents here -->
    
    <!--    </com.google.android.material.appbar.AppBarLayout>-->
    
    <!--  </androidx.coordinatorlayout.widget.CoordinatorLayout>-->
    
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
  2. W swoim fragmencie lub aktywności znajdź odniesienie do ComposeView, dodano i wywołaj dla niego metodę setContent. W treści metody ustaw element Scaffold jako jego treść:

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

  3. W treściach Scaffold dodaj główne treści ekranu. Ponieważ główną treścią w powyższym kodzie XML jest ViewPager2, użyjemy funkcji ViewPager2 HorizontalPager, co jest jego odpowiednikiem w usłudze Compose. Lambda content w komponencie Scaffold otrzymuje też instancję PaddingValues, która powinna zostać zastosowana do katalogu głównego treści. Aby zastosować to samo, możesz użyć polecenia Modifier.padding 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 boksów na treści dostępnych w usłudze Scaffold, aby dodać więcej elementów na ekranie i przenieść pozostałe widoki podrzędne. Możesz użyć pola topBar, aby dodać TopAppBar, a pola floatingActionButton, aby podać 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 */ }
        }
    }

Typowe zastosowania

Zwijanie i rozwijanie pasków narzędzi

Aby w systemie widoku zwinąć i rozwinąć pasek narzędzi za pomocą przycisków CoordinatorLayout, używasz tagu AppBarLayout jako kontenera dla paska narzędzi. Możesz wtedy podać Behavior do layout_behavior w formacie XML na powiązanym elemencie przewijanym Wyświetl (np. RecyclerView lub NestedScrollView), aby zadeklarować, jak pasek narzędzi zwija się podczas przewijania.

Podobny efekt możesz uzyskać w sekcji Compose TopAppBarScrollBehavior Aby na przykład wdrożyć pasek narzędzi, który można zwinąć lub rozwinąć, tak aby był widoczny po przewinięciu w górę, wykonaj te czynności:

  1. Zadzwoń pod numer TopAppBarDefaults.enterAlwaysScrollBehavior(), aby utworzyć TopAppBarScrollBehavior
  2. Prześlij utworzony TopAppBarScrollBehavior do TopAppBar.
  3. Połącz NestedScrollConnection za pomocą Modifier.nestedScroll na serwerze Scaffold, aby szkielet mógł otrzymywać zdarzenia przewijania zagnieżdżonego podczas przewijania treści do góry i do dołu. Dzięki temu pasek aplikacji może odpowiednio zwijać/rozwijać się 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

Aby dostosować efekt animacji zwijania/rozwijania, możesz podać kilka parametrów enterAlwaysScrollBehavior. TopAppBarDefaults udostępnia też inne TopAppBarScrollBehavior, takie jak exitUntilCollapsedScrollBehavior, które rozwija pasek aplikacji tylko wtedy, gdy przewiniesz treści do końca.

Aby utworzyć całkowicie niestandardowy efekt (np. efekt paralaksy), możesz też utworzyć własną NestedScrollConnection i ręcznie przesuwać pasek narzędzi podczas przewijania treści. Zapoznaj się z przykładem przewijania zagnieżdżonego na stronie AOSP, aby dowiedzieć się przykładowy kod.

Szuflady

W przypadku widoków schowanka nawigacyjna jest implementowana za pomocą widoku wyższego poziomu DrawerLayout. Z kolei CoordinatorLayout to DrawerLayout w widoku podrzędnym. Element DrawerLayout zawiera też inny widok podrzędny, np. NavigationView, aby wyświetlić opcje nawigacji w schowku.

W komponencie tworzenia wiadomości możesz zaimplementować panel nawigacji 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 Drawers.

Paski powiadomień

Scaffold udostępnia slot snackbarHost, który może przyjmować komponent SnackbarHost, aby wyświetlić element 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 powiadomień.

Więcej informacji

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

.