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

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

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

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

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

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

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

  3. ในเนื้อหาของ Scaffold ให้เพิ่มเนื้อหาหลักของหน้าจอลงในเนื้อหา เนื่องจากเนื้อหาหลักใน XML ด้านบนคือ ViewPager2 เราจึงจะใช้ HorizontalPager ซึ่งเป็นองค์ประกอบที่เทียบเท่าใน Compose แลมบ์ดา content ของ 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 มีให้เพื่อเพิ่มองค์ประกอบอื่นๆ ของหน้าจอและย้ายข้อมูล View ย่อยที่เหลือ คุณสามารถใช้ช่อง 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 */ }
        }
    }

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

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

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

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

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

    // 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 ซึ่งจะขยาย App Bar ก็ต่อเมื่อ เนื้อหาเลื่อนลงจนสุดเท่านั้น

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

ลิ้นชัก

เมื่อใช้ View คุณจะใช้ลิ้นชักการนำทางโดยใช้ DrawerLayoutเป็น View รูท ซึ่ง CoordinatorLayout จะเป็น View ย่อยของ DrawerLayout DrawerLayout ยังมี View ย่อยอีกรายการ เช่น 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 ได้จากแหล่งข้อมูลต่อไปนี้