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

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

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

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

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

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

    ```xml

    <!-- AppBarLayout contents here -->
    

    ```

  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 บนมุมมองที่เลื่อนได้ที่เกี่ยวข้อง (เช่น 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 คุณสามารถใช้ลิ้นชักการนำทางได้โดยใช้คอมโพสิเบิล 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
    // ...
}

ดูข้อมูลเพิ่มเติมได้ที่ Snackbar

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

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