ย้ายข้อมูล CoordinatorLayout ไปยังเขียน

CoordinatorLayout คือ ViewGroup ที่ใช้สำหรับเลย์เอาต์ที่ซับซ้อน ซ้อนทับ และฝัง โดยใช้เป็นคอนเทนเนอร์เพื่อเปิดใช้การโต้ตอบบางอย่างใน Material Design เช่น การขยาย/ยุบแถบเครื่องมือและชีตด้านล่าง สำหรับมุมมองที่อยู่ในนั้น

ในเครื่องมือเขียน CoordinatorLayout ที่เทียบเท่าที่สุดคือ Scaffold Scaffold มีช่องสำหรับเนื้อหาเพื่อรวม Material Component เข้าด้วยกันเป็นรูปแบบและอินเทอร์แอกชันหน้าจอทั่วไป หน้านี้จะอธิบายวิธีย้ายข้อมูลการใช้งาน CoordinatorLayout ไปใช้ Scaffold ใน Compose

ขั้นตอนการย้ายข้อมูล

หากต้องการย้ายข้อมูล CoordinatorLayout ไปยัง Scaffold ให้ทำตามขั้นตอนต่อไปนี้

  1. ในตัวอย่างข้อมูลด้านล่าง CoordinatorLayout มี AppBarLayout สำหรับ ที่มี ToolBar, ViewPager และ FloatingActionButton คอมเมนต์CoordinatorLayoutและรายการย่อยของ CoordinatorLayout ออกจากลําดับชั้น UI แล้วเพิ่ม 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. ในข้อมูลโค้ดหรือกิจกรรม ให้รับการอ้างอิง ComposeView ที่เพิ่งเพิ่มและเรียกใช้เมธอด setContent กับ ComposeView ในส่วนเนื้อหาของเมธอด ให้ตั้งค่า Scaffold เป็นเนื้อหาดังนี้

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

  3. ในเนื้อหาของ Scaffold ให้เพิ่มเนื้อหาหลักของหน้าจอในนั้น เนื่องจากเนื้อหาหลักใน XML ด้านบนคือ ViewPager2 เราจะใช้ HorizontalPager ซึ่งเป็นองค์ประกอบที่เทียบเท่าของ Compose content lambda ของ Scaffold ยังได้รับอินสแตนซ์ของ PaddingValues ที่จะนำไปใช้กับรูทเนื้อหาด้วย คุณสามารถใช้ Modifier.padding เพื่อใช้ PaddingValues เดียวกันกับ HorizontalPager ได้

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

  4. ใช้ช่องเนื้อหาอื่นๆ ที่ Scaffold มีให้เพื่อเพิ่มองค์ประกอบหน้าจออื่นๆ และย้ายข้อมูลมุมมองย่อยที่เหลือ คุณสามารถใช้ช่อง topBar เพื่อเพิ่ม TopAppBar และช่อง 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 */ }
        }
    }

กรณีการใช้งานทั่วไป

ยุบและขยายแถบเครื่องมือ

ในระบบมุมมอง หากต้องการยุบและขยายแถบเครื่องมือด้วย CoordinatorLayout คุณต้องใช้ AppBarLayout เป็นคอนเทนเนอร์สำหรับแถบเครื่องมือ จากนั้นคุณสามารถระบุ Behavior ผ่าน layout_behavior ใน XML ในมุมมองที่เลื่อนได้ที่เกี่ยวข้อง (เช่น RecyclerView หรือ NestedScrollView) เพื่อประกาศวิธียุบ/ขยายแถบเครื่องมือขณะเลื่อน

ในเครื่องมือเขียน คุณจะสร้างเอฟเฟกต์ที่คล้ายกันได้ผ่าน TopAppBarScrollBehavior เช่น หากต้องการใช้แถบเครื่องมือแบบยุบ/ขยายเพื่อให้แถบเครื่องมือปรากฏขึ้นเมื่อคุณเลื่อนขึ้น ให้ทำตามขั้นตอนต่อไปนี้

  1. โทรหา TopAppBarDefaults.enterAlwaysScrollBehavior() เพื่อสร้าง TopAppBarScrollBehavior
  2. ส่ง TopAppBarScrollBehavior ที่สร้างขึ้นให้กับ TopAppBar
  3. เชื่อมต่อ NestedScrollConnection ผ่าน Modifier.nestedScroll ใน Scaffold เพื่อให้ Scaffold ได้รับการเลื่อนเหตุการณ์ที่ฝังอยู่เมื่อเนื้อหาที่เลื่อนได้เลื่อนขึ้น/ลง วิธีนี้จะช่วยให้แถบแอปที่รวมอยู่สามารถยุบ/ขยายได้อย่างเหมาะสมขณะที่เนื้อหาเลื่อน

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

ปรับแต่งเอฟเฟกต์การเลื่อนแบบยุบ/ขยาย

คุณสามารถระบุพารามิเตอร์หลายรายการสำหรับ enterAlwaysScrollBehavior เพื่อปรับแต่งเอฟเฟกต์ภาพเคลื่อนไหวแบบยุบ/ขยาย TopAppBarDefaults ยังมีTopAppBarScrollBehaviorอื่นๆ ด้วย เช่น exitUntilCollapsedScrollBehavior ซึ่งจะขยายแถบแอปเฉพาะเมื่อเลื่อนเนื้อหาลงจนสุดเท่านั้น

หากต้องการสร้างเอฟเฟกต์ที่กำหนดเองทั้งหมด (เช่น เอฟเฟกต์ภาพพาโนรามา) คุณยังสร้าง NestedScrollConnection ของคุณเองและเลื่อนแถบเครื่องมือด้วยตนเองได้ขณะที่เนื้อหาเลื่อน ดูตัวอย่างโค้ดได้ที่ตัวอย่างการเลื่อนที่ซ้อนกันใน AOSP

ตู้ลิ้นชัก

เมื่อใช้มุมมอง คุณจะติดตั้งใช้งานลิ้นชักการนำทางได้โดยใช้ DrawerLayout เป็นมุมมองรูท CoordinatorLayout ของคุณจึงเป็นแหล่งข้อมูลย่อยของDrawerLayout DrawerLayout ยังมีมุมมองย่อยอีกรายการหนึ่ง เช่น NavigationView เพื่อแสดงตัวเลือกการนำทางในลิ้นชัก

ใน Compose คุณสามารถติดตั้งใช้งานลิ้นชักการนำทางได้โดยใช้คอมโพสิเบิล ModalNavigationDrawer ModalNavigationDrawer มีช่อง drawerContent สำหรับลิ้นชักและช่อง content สำหรับเนื้อหาของหน้าจอ

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

ดูข้อมูลเพิ่มเติมได้ในลิ้นชัก

แถบแสดงข้อความ

Scaffold มีช่อง snackbarHost ซึ่งรับ SnackbarHost ที่คอมโพสิเบิลเพื่อแสดง 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
    // ...
}

ดูข้อมูลเพิ่มเติมได้ในแถบข้อมูล

ดูข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูล CoordinatorLayout ไปยัง Compose ได้ที่แหล่งข้อมูลต่อไปนี้