CoordinatorLayout'u Compose'a Taşı

CoordinatorLayout; karmaşık, çakışan ve iç içe yerleştirilmiş düzenleri sağlayan bir ViewGroup'dir. İçinde bulunan Görünümler için, genişleyen/daraltılan araç çubukları ve alt sayfalar gibi belirli Materyal Tasarım etkileşimlerini etkinleştirmek amacıyla bir kapsayıcı olarak kullanılır.

Compose'da CoordinatorLayout öğesinin en yakın eşdeğeri Scaffold değeridir. Scaffold, Materyal Bileşenleri yaygın ekran kalıpları ve etkileşimlerinde birleştirmek için içerik alanları sağlar. Bu sayfada, Composer'da Scaffold kullanmak için CoordinatorLayout uygulamanızı nasıl taşıyacağınız açıklanmaktadır.

Taşıma adımları

CoordinatorLayout numarasını Scaffold hizmetine taşımak için şu adımları uygulayın:

  1. Aşağıdaki snippet'te CoordinatorLayout; ToolBar, ViewPager ve FloatingActionButton içeren bir AppBarLayout içeriyor. Kullanıcı arayüzü hiyerarşinizden CoordinatorLayout ve alt öğelerini yorumlayıp değiştirmek için ComposeView ekleyin.

    <!--  <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. Bölümünüzde veya Etkinliğinizde, az önce eklediğiniz ComposeView için bir referans bulun ve bunun üzerindeki setContent yöntemini çağırın. Yöntemin gövdesinde, içeriği olarak bir Scaffold ayarlayın:

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

  3. Ekranınızın birincil içeriğini Scaffold içeriğinizin içine ekleyin. Yukarıdaki XML'deki birincil içerik bir ViewPager2 olduğundan, bu içeriğin Compose'daki eşdeğeri olan bir HorizontalPager kullanacağız. Scaffold öğesinin content lambdası, içerik köküne uygulanması gereken PaddingValues örneği de alır. Aynı PaddingValues öğesini HorizontalPager öğesine uygulamak için Modifier.padding kullanabilirsiniz.

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

  4. Daha fazla ekran öğesi eklemek ve kalan alt Görünümleri taşımak için Scaffold tarafından sağlanan diğer içerik alanlarını kullanın. TopAppBar eklemek için topBar yuvasını, FloatingActionButton eklemek için floatingActionButton yuvasını kullanabilirsiniz.

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

Yaygın kullanım alanları

Araç çubuklarını daraltma ve genişletme

View sisteminde, araç çubuğunu CoordinatorLayout ile daraltmak ve genişletmek için araç çubuğu için bir kapsayıcı olarak AppBarLayout kullanırsınız. Ardından, araç çubuğunu kaydırdıkça araç çubuğunun nasıl daralacağını/genişletileceğini belirtmek için ilişkili kaydırılabilir görünümde (RecyclerView veya NestedScrollView gibi) XML'de Behavior ile layout_behavior aralığında bir değer belirtebilirsiniz.

Compose'da TopAppBarScrollBehavior ile de benzer bir efekt elde edebilirsiniz. Örneğin, yukarı kaydırdığınızda araç çubuğunun görünmesi için daraltılabilen/genişleyen bir araç çubuğu uygulamak için şu adımları uygulayın:

  1. TopAppBarScrollBehavior oluşturmak için TopAppBarDefaults.enterAlwaysScrollBehavior() numaralı telefonu arayın.
  2. Oluşturulan TopAppBarScrollBehavior değerini TopAppBar ile paylaşın.
  3. Scaffold'un kaydırılabilir içerik yukarı/aşağı kaydırılırken iç içe kaydırma etkinlikleri alabilmesi için Scaffold üzerinde Modifier.nestedScroll aracılığıyla NestedScrollConnection bağlantısını bağlayın. Böylece, içerik kaydırılırken içerdiği uygulama çubuğu uygun şekilde daraltılabilir/genişletilebilir.

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

Daraltma/genişleyen kaydırma efektini özelleştirme

Daraltma/genişleyen animasyon efektini özelleştirmek için enterAlwaysScrollBehavior için çeşitli parametreler sağlayabilirsiniz. TopAppBarDefaults, exitUntilCollapsedScrollBehavior gibi yalnızca içerik tamamen aşağı kaydırıldığında uygulama çubuğunu genişleten başka TopAppBarScrollBehavior sağlar.

Tamamen özel bir efekt (ör. paralaks efekti) oluşturmak için kendi NestedScrollConnection efektinizi de oluşturabilir ve içerik kaydırılırken araç çubuğunu manuel olarak kaydırabilirsiniz. Kod örneği için AOSP'deki İç içe kaydırma örneği bölümüne bakın.

Çekmeceler

Görünümler'de, kök görünümü olarak DrawerLayout kullanarak bir gezinme çekmecesi uygularsınız. Bu durumda CoordinatorLayout, DrawerLayout alt görünümüdür. DrawerLayout, çekmecedeki gezinme seçeneklerini görüntülemek için başka bir alt görünüm (ör. NavigationView) da içerir.

Compose'da ModalNavigationDrawer composable'ı kullanarak gezinme çekmecesi uygulayabilirsiniz. ModalNavigationDrawer, çekmece için drawerContent bir yuva ve ekranın içeriği için content bir yuva sunar.

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

Daha fazla bilgi edinmek için Çekmeceler bölümüne bakın.

Snackbar'lar

Scaffold, Snackbar görüntülemek için SnackbarHost composable'ını kabul edebilen bir snackbarHost slotu sağlar.

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

Daha fazla bilgi edinmek için Atıştırmalıklar başlıklı makaleyi inceleyin.

Daha fazla bilgi

CoordinatorLayout öğesini Compose'a taşıma hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın: