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

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

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

ขั้นตอนการย้ายโปรเจ็กต์

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

  1. ในข้อมูลโค้ดด้านล่าง CoordinatorLayout มี AppBarLayout สำหรับ มี ToolBar, ViewPager และ FloatingActionButton แสดงความคิดเห็น ใน CoordinatorLayout และองค์ประกอบย่อยจากลำดับชั้น UI แล้วเพิ่ม ComposeView เพื่อแทนที่

    ```xml

    <!-- AppBarLayout contents here -->
    

    ```

  2. ใน Fragment หรือ Activity ให้รับการอ้างอิงถึง ComposeView ที่คุณเพิ่งเพิ่มและเรียกใช้เมธอด setContent ใน Fragment หรือ Activity นั้น ในเนื้อหาของเมธอด ให้ตั้งค่า 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 คุณสามารถสร้างเอฟเฟกต์ที่คล้ายกันได้ผ่าน 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

ลิ้นชัก

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

ใน Compose คุณสามารถใช้ลิ้นชักการนำทางได้โดยใช้ Composable ของ 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 Composable เพื่อแสดง 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 ได้ที่แหล่งข้อมูลต่อไปนี้