CoordinatorLayout zu Compose migrieren

CoordinatorLayout ist eine ViewGroup, die komplexe, sich überschneidende und verschachtelte Layouts. Er dient als Container, um bestimmte Material Design-Elemente zu ermöglichen, Interaktionen, wie Symbolleisten zum Maximieren und Minimieren, und Ansichten am unteren Rand für Ansichten die in ihr enthalten sind.

Das nächste Äquivalent zu CoordinatorLayout in Compose ist ein Scaffold Ein Scaffold bietet Inhaltsbereiche zum Kombinieren von Material. Komponenten zu gängigen Bildschirmmustern und Interaktionen. Auf dieser Seite wird beschrieben, Sie können Ihre CoordinatorLayout-Implementierung zur Verwendung von Scaffold in Schreiben.

Migrationsschritte

So migrieren Sie CoordinatorLayout zu Scaffold:

  1. Im folgenden Snippet enthält CoordinatorLayout ein AppBarLayout für mit einem ToolBar, einem ViewPager und einem FloatingActionButton. Kommentieren das CoordinatorLayout und seine untergeordneten Elemente aus der UI-Hierarchie aus und fügen Sie ein ComposeView, um ihn zu ersetzen.

    <!--  <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. Ermitteln Sie in Ihrem Fragment oder Ihrer Aktivität einen Verweis auf das ComposeView, das Sie und die setContent-Methode dafür aufrufen. Im Hauptteil der Methode Scaffold als Inhalt festlegen:

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

  3. Füge im Inhalt deiner Scaffold den Hauptinhalt deines Bildschirms in . Da der Hauptinhalt in der obigen XML-Datei ein ViewPager2 ist, verwenden wir ein HorizontalPager, das Compose-Äquivalent dafür. Lambda von content des Scaffold erhält auch eine Instanz von PaddingValues, die auf das Inhaltsstammverzeichnis angewendet wird. Mit Modifier.padding können Sie PaddingValues zu HorizontalPager.

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

  4. Andere von Scaffold bereitgestellte Inhaltsbereiche verwenden, um weitere Bildschirmelemente hinzuzufügen und die verbleibenden untergeordneten Ansichten migrieren. Über die Anzeigenfläche topBar können Sie eine TopAppBar und dem Slot floatingActionButton, um eine 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 */ }
        }
    }

Gängige Anwendungsfälle

Symbolleisten minimieren und maximieren

Gehen Sie zum Minimieren und Maximieren der Symbolleiste mit CoordinatorLayout im Ansichtssystem so vor: verwenden Sie ein AppBarLayout als Container für die Symbolleiste. Sie können dann eine Behavior bis layout_behavior in XML auf dem zugehörigen scrollbaren Element Ansicht (wie RecyclerView oder NestedScrollView), um zu erklären, wie die Symbolleiste wird beim Scrollen minimiert/maximiert.

Einen ähnlichen Effekt erzielen Sie in der Funktion „Schreiben“ TopAppBarScrollBehavior Um beispielsweise eine Anzeige zum Minimieren oder Maximieren sodass die Symbolleiste angezeigt wird, wenn Sie nach oben scrollen:

  1. Rufen Sie TopAppBarDefaults.enterAlwaysScrollBehavior() auf, um ein TopAppBarScrollBehavior.
  2. Stellen Sie den erstellten TopAppBarScrollBehavior für den TopAppBar bereit.
  3. Verbinden Sie NestedScrollConnection über Modifier.nestedScroll auf der Scaffold festlegen, damit das Scaffold verschachtelte Scroll-Ereignisse empfangen kann, scrollbarer Inhalt nach oben/unten. So kann die eingeschlossene App-Leiste Minimieren/Maximieren, wenn der Inhalt scrollt.

    // 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 */
        // ...
    }

Minimieren/Maximieren des Scrolleffekts anpassen

Sie können mehrere Parameter für enterAlwaysScrollBehavior angeben, um den Animationseffekt für die Minimierung/Maximierung anpassen. TopAppBarDefaults stellt andere TopAppBarScrollBehavior wie exitUntilCollapsedScrollBehavior, wodurch die App-Leiste nur maximiert wird, wenn bis ganz nach unten gescrollt wird.

Um einen vollständig benutzerdefinierten Effekt zu erstellen (z. B. einen Parallaxe-Effekt), kannst du Sie können auch Ihr eigenes NestedScrollConnection erstellen und die Symbolleiste manuell verschieben als der Inhalt scrollt. Unter Beispiel für verschachteltes Scrollen auf AOSP finden Sie .

Schubladen

Mit der Funktion "Ansichten" implementieren Sie eine Navigationsleiste mithilfe eines DrawerLayout als Stammansicht. Ihre CoordinatorLayout ist wiederum ein untergeordnete Ansicht von DrawerLayout. DrawerLayout enthält auch ein weiteres untergeordnetes Element wie zum Beispiel NavigationView, um die Navigationsoptionen in der Ansicht Leiste.

In Compose können Sie eine Navigationsleiste implementieren, indem Sie die ModalNavigationDrawer zusammensetzbar. ModalNavigationDrawer bietet ein drawerContent Slot für die Leiste und content-Slot für den Inhalte.

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

Weitere Informationen finden Sie unter Drawer.

Snackbars

Scaffold bietet einen snackbarHost-Slot, der einen SnackbarHost akzeptieren kann zusammensetzbar ist, um eine Snackbar anzuzeigen.

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
    // ...
}

Weitere Informationen findest du unter Snackbars.

Weitere Informationen

Weitere Informationen zur Migration eines CoordinatorLayout zu Compose finden Sie in der folgenden Ressourcen: