Jetpack Compose ช่วยให้การออกแบบและสร้าง UI ของแอปง่ายขึ้นมาก เขียน เปลี่ยนรูปแบบสถานะเป็นองค์ประกอบ UI ผ่าน:
- การจัดวางองค์ประกอบ
- การจัดวางองค์ประกอบ
- ภาพวาดองค์ประกอบ
เอกสารนี้เน้นที่การจัดวางองค์ประกอบ โดยอธิบายบางส่วนของสิ่งปลูกสร้าง Compose บล็อกจะช่วยให้คุณสามารถจัดวางองค์ประกอบ UI ของคุณ
เป้าหมายของเลย์เอาต์ใน Compose
การใช้ระบบเลย์เอาต์ของ Jetpack Compose มีเป้าหมายหลัก 2 ประการ ดังนี้
- ประสิทธิภาพสูง
- ความสามารถในการเขียนเลย์เอาต์ที่กำหนดเองได้โดยง่าย
พื้นฐานของฟังก์ชันที่ประกอบกันได้
ฟังก์ชันที่ประกอบกันได้เป็นองค์ประกอบพื้นฐานของการเขียน Composable
คือฟังก์ชันที่ปล่อย Unit
ซึ่งอธิบาย UI บางส่วนของคุณ
จะรับอินพุตและสร้างสิ่งที่แสดงบนหน้าจอ สำหรับข้อมูลเพิ่มเติม
เกี่ยวกับ Composable โปรดดูที่บทความ
รูปแบบต่อไปนี้
ฟังก์ชัน Composable อาจปล่อยองค์ประกอบ UI หลายรายการ แต่ถ้าคุณไม่ ให้แนวทางในการจัดเรียงข้อความ Compose อาจจัดเรียง องค์ประกอบบางอย่างในลักษณะที่คุณไม่ต้องการ ตัวอย่างเช่น โค้ดนี้จะสร้างข้อความสองข้อความ องค์ประกอบ:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
Compose จะซ้อนองค์ประกอบข้อความโดยไม่มีคำแนะนำเกี่ยวกับวิธีที่คุณต้องการจัดเรียงข้อความ ทับกัน ซึ่งทำให้อ่านไม่ได้
Compose มีคอลเล็กชันเลย์เอาต์ที่พร้อมใช้งานเพื่อช่วยคุณในการจัดเรียง องค์ประกอบ UI และช่วยให้กำหนดเลย์เอาต์ที่มีความพิเศษเฉพาะตัวของคุณได้ง่ายขึ้น
คอมโพเนนต์เลย์เอาต์มาตรฐาน
ในหลายกรณี คุณสามารถใช้เพียงเลย์เอาต์มาตรฐานของ Compose องค์ประกอบ
ใช้
Column
เพื่อวางรายการในแนวตั้งบนหน้าจอ
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
ในทำนองเดียวกัน ให้ใช้
Row
เพื่อวางรายการในแนวนอนบนหน้าจอ ทั้งการสนับสนุนของ Column
และ Row
โดยกำหนดค่าการปรับแนวขององค์ประกอบที่มีอยู่
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
ใช้ Box
เพื่อวางองค์ประกอบทับองค์ประกอบอื่น นอกจากนี้ Box
ยังรองรับการกำหนดค่าการปรับแนวที่เจาะจงขององค์ประกอบที่อยู่ภายในด้วย
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
โดยทั่วไปแล้ว องค์ประกอบเหล่านี้คือสิ่งที่คุณต้องการ คุณเขียนฟังก์ชันที่ประกอบกันได้เพื่อรวมเลย์เอาต์เหล่านี้เข้าด้วยกันเป็นเลย์เอาต์ที่ซับซ้อนมากขึ้นที่เหมาะกับแอปได้
หากต้องการกำหนดตำแหน่งของบุตรหลานภายใน Row
ให้ตั้งค่า horizontalArrangement
และ
verticalAlignment
อาร์กิวเมนต์ สำหรับ Column
ให้ตั้งค่า verticalArrangement
และ
horizontalAlignment
อาร์กิวเมนต์:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
โมเดลเลย์เอาต์
ในรูปแบบเลย์เอาต์ แผนผัง UI จะวางอยู่ในบัตรผ่านครั้งเดียว แต่ละโหนด จะวัดผลตัวเองก่อน จากนั้นจึงวัดเด็กซ้ำๆ ผ่าน จำกัดขนาดต้นไม้ให้เด็กได้ โหนดใบไม้ก็จะมีขนาดและ ด้วยขนาดที่แก้ไขแล้วและคำแนะนำตำแหน่งในตำแหน่งที่ส่งคืน ต้นไม้
ใช้เวลาสั้นๆ ผู้ปกครองวัดผลก่อนบุตรหลาน แต่มีขนาดและวางหลัง บุตรหลานของตน
ลองพิจารณาฟังก์ชัน SearchResult
ต่อไปนี้
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
ฟังก์ชันนี้จะแสดงโครงสร้าง UI ต่อไปนี้
SearchResult
Row
Image
Column
Text
Text
ในตัวอย่าง SearchResult
เลย์เอาต์แบบต้นไม้ UI จะเป็นไปตามลำดับต่อไปนี้
- ระบบขอให้วัดโหนดรูท
Row
- โหนดราก
Row
ขอให้โหนดย่อยแรกImage
ทำการวัด Image
เป็นโหนดย่อย (ไม่มีโหนดย่อย) จึงรายงานขนาด และแสดงผลคำแนะนำตำแหน่ง- โหนดราก
Row
ขอให้โหนดย่อยลำดับที่ 2 ซึ่งก็คือColumn
วัดค่า - โหนด
Column
ขอให้วัดย่อยText
รายการแรก - โหนด
Text
แรกคือโหนด Leaf จึงรายงานขนาดและแสดงผล คำแนะนำตำแหน่ง - โหนด
Column
ขอให้วัดย่อยText
รายการที่ 2 - โหนด
Text
ที่ 2 เป็นโหนด Leaf จึงรายงานขนาดและแสดงผล คำแนะนำตำแหน่ง - เมื่อโหนด
Column
วัด ปรับขนาด และวางโหนดย่อยแล้ว สามารถกำหนดขนาดและตำแหน่งของตัวเอง - เมื่อโหนดราก
Row
ได้วัด ปรับขนาด และวางโหนดย่อยแล้ว สามารถกำหนดขนาดและตำแหน่งของตัวเอง
ประสิทธิภาพ
การเขียนสามารถมีประสิทธิภาพสูงโดยการวัดผลเด็กเพียงครั้งเดียว บัตรผ่านเดียว การวัดนั้นดีสำหรับประสิทธิภาพ ทำให้ Compose สามารถจัดการ แผนผัง UI หากองค์ประกอบหนึ่งวัดย่อย 2 ครั้งและองค์ประกอบย่อยนั้นวัดแต่ละรายการ ประมาณ 2 ครั้ง และต่อๆ ไป ความพยายามเพียงครั้งเดียวในการจัดวาง UI ทั้งหมด ทำงานหนัก ทำให้แอปมีประสิทธิภาพอยู่เสมอ
หากเลย์เอาต์ต้องใช้การวัดหลายแบบด้วยเหตุผลบางประการ Compose จะมี ระบบพิเศษ การวัดภายใน คุณอ่านเพิ่มเติมเกี่ยวกับฟีเจอร์นี้ได้ ในการวัดภายในใน Compose Layouts
เนื่องจากการวัดและการวางตำแหน่งเป็นช่วงย่อยที่แตกต่างกันของการส่งผ่านเลย์เอาต์ สามารถทำการเปลี่ยนแปลงที่มีผลต่อตำแหน่งของรายการเท่านั้น ไม่ใช่การวัด แยกกัน
การใช้ตัวแก้ไขในเลย์เอาต์
ตามที่อธิบายไว้ในตัวปรับแต่ง Compose คุณสามารถใช้
คีย์ตัวปรับแต่งเพื่อตกแต่งหรือเพิ่ม Composable ตัวปรับแต่งเป็นสิ่งสำคัญ
ในการปรับแต่งเลย์เอาต์ ตัวอย่างเช่น ตรงนี้เรารวมตัวปรับแต่งหลายรายการ
เพื่อปรับแต่ง ArtistCard
:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
ในโค้ดข้างต้น คุณสังเกตเห็นฟังก์ชันของตัวปรับแต่งต่างๆ ที่ใช้งานร่วมกัน
clickable
สร้างการตอบสนองที่ประกอบกันได้ต่อข้อมูลจากผู้ใช้ และแสดงระลอกคลื่นpadding
วางพื้นที่รอบๆ องค์ประกอบfillMaxWidth
ทำให้ Composable เติมความกว้างสูงสุดตามที่กำหนดไว้จาก ระดับบนสุดsize()
จะระบุความกว้างและความสูงที่ต้องการขององค์ประกอบ
เลย์เอาต์แบบเลื่อนได้
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลย์เอาต์แบบเลื่อนได้ใน เขียนเอกสารประกอบเกี่ยวกับท่าทางสัมผัส
สำหรับรายการและลิสต์แบบ Lazy Loading โปรดดูที่ เขียนเอกสารประกอบเกี่ยวกับรายการ
เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์
เลย์เอาต์ควรออกแบบโดยคำนึงถึงการวางแนวหน้าจอที่แตกต่างกัน และขนาดของอุปกรณ์ เขียนข้อเสนอเริ่มต้น 2-3 กลไกในการ ช่วยปรับเลย์เอาต์ที่ประกอบกันได้ให้เข้ากับการกำหนดค่าหน้าจอในลักษณะต่างๆ
ข้อจำกัด
เพื่อให้ทราบข้อจำกัดที่มาจากองค์ประกอบระดับบนสุดและออกแบบเลย์เอาต์
คุณสามารถใช้ BoxWithConstraints
ได้ การวัดผล
ข้อจำกัด
ได้ในขอบเขตของเนื้อหา lambda คุณสามารถใช้การวัดเหล่านี้ได้
ข้อจำกัดในการเขียนรูปแบบที่แตกต่างกันสำหรับการกำหนดค่าหน้าจอที่แตกต่างกัน
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
เลย์เอาต์แบบอิงตามช่อง
Compose มี Composable จำนวนมากโดยอิงตาม Material
ออกแบบด้วย
ทรัพยากร Dependency androidx.compose.material:material
(รวมไว้เมื่อสร้าง
Compose Project ใน Android Studio) เพื่อช่วยให้การสร้าง UI เป็นเรื่องง่าย องค์ประกอบเช่น
Drawer
FloatingActionButton
,
และ TopAppBar
ได้รับการระบุทั้งหมด
คอมโพเนนต์ Material มีการใช้ slot API เป็นจำนวนมาก ซึ่งเป็นการนำเสนอรูปแบบ Compose ใน
เพื่อเพิ่มเลเยอร์ของการปรับแต่งทับ Composable วิธีนี้ทำให้
มีความยืดหยุ่นมากกว่า เนื่องจากจะยอมรับองค์ประกอบย่อยที่สามารถกำหนดค่า
โดยไม่ต้องแสดงพารามิเตอร์การกำหนดค่าทั้งหมดของหน่วยย่อย
ช่องจะปล่อยพื้นที่ว่างใน UI ไว้เพื่อให้นักพัฒนาแอปป้อนข้อมูลได้ตามต้องการ สำหรับ
ตัวอย่างเช่น ช่องเหล่านี้คือช่องที่คุณสามารถปรับแต่งใน
TopAppBar
:
คำสั่ง Composable มักจะใช้ lambda ที่ประกอบกันได้ content
( content: @Composable
() -> Unit
) Slot API แสดงพารามิเตอร์ content
หลายรายการสำหรับการใช้งานที่เฉพาะเจาะจง
ตัวอย่างเช่น TopAppBar
อนุญาตให้คุณระบุเนื้อหาสำหรับ title
navigationIcon
และ actions
ตัวอย่างเช่น
Scaffold
ช่วยให้คุณใช้ UI ด้วยโครงสร้างเลย์เอาต์แบบดีไซน์ Material ได้
Scaffold
มีช่องสำหรับคอมโพเนนต์ Material ระดับบนสุดที่พบได้บ่อยที่สุด
เช่น TopAppBar
BottomAppBar
,
FloatingActionButton
และ Drawer
โดยการใช้
Scaffold
คุณสามารถตรวจสอบว่าคอมโพเนนต์เหล่านี้อยู่ในตำแหน่งที่ถูกต้องและ
ทำงานร่วมกันอย่างถูกต้อง
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ตัวปรับแต่งการเขียน
- Kotlin สำหรับ Jetpack Compose
- คอมโพเนนต์และเลย์เอาต์ของวัสดุ