หน้านี้ให้ภาพรวมระดับสูงของเลเยอร์สถาปัตยกรรมที่ประกอบกันเป็น Jetpack Compose และหลักการสำคัญที่ใช้ในการออกแบบนี้
Jetpack Compose ไม่ใช่โปรเจ็กต์แบบโมโนลิธโปรเจ็กต์เดียว แต่สร้างขึ้นจากโมดูลหลายโมดูลที่ประกอบเข้าด้วยกันเพื่อสร้างสแต็กที่สมบูรณ์ การทำความเข้าใจ โมดูลต่างๆ ที่ประกอบกันเป็น Jetpack Compose จะช่วยให้คุณทำสิ่งต่อไปนี้ได้
- ใช้ระดับการแยกรายละเอียดที่เหมาะสมเพื่อสร้างแอปหรือไลบรารี
- ทำความเข้าใจเมื่อคุณสามารถ "เลื่อนลง" ไปยังระดับที่ต่ำกว่าเพื่อควบคุมหรือปรับแต่งได้มากขึ้น
- ลดทรัพยากร Dependency
เลเยอร์
เลเยอร์หลักของ Jetpack Compose มีดังนี้
รูปที่ 1 เลเยอร์หลักของ Jetpack Compose
เลเยอร์แต่ละเลเยอร์สร้างขึ้นจากเลเยอร์ระดับล่าง โดยรวมฟังก์ชันการทำงานเพื่อสร้าง คอมโพเนนต์ระดับสูง แต่ละเลเยอร์สร้างขึ้นบน API สาธารณะของเลเยอร์ที่ต่ำกว่า เพื่อยืนยันขอบเขตของโมดูลและช่วยให้คุณแทนที่เลเยอร์ใดก็ได้หาก ต้องการ มาดูเลเยอร์เหล่านี้จากล่างขึ้นบนกัน
- รันไทม์
- โมดูลนี้จะอธิบายพื้นฐานของรันไทม์ Compose เช่น
remember
mutableStateOf
คำอธิบายประกอบ@Composable
และSideEffect
คุณอาจพิจารณาสร้างเลเยอร์นี้โดยตรงหากต้องการเพียงความสามารถในการจัดการโครงสร้างของ Compose ไม่ใช่ UI - UI
- เลเยอร์ UI ประกอบด้วยโมดูลหลายโมดูล (
ui-text
,ui-graphics
,ui-tooling
, ฯลฯ) โมดูลเหล่านี้ใช้พื้นฐานของชุดเครื่องมือ UI เช่นLayoutNode
,Modifier
, ตัวแฮนเดิลอินพุต เลย์เอาต์ที่กำหนดเอง และการวาด คุณอาจพิจารณาสร้างเลเยอร์นี้หาก ต้องการเพียงแนวคิดพื้นฐานของชุดเครื่องมือ UI - มูลนิธิ
- โมดูลนี้มีบล็อกการสร้างที่ไม่ขึ้นกับระบบการออกแบบสำหรับ Compose UI
เช่น
Row
และColumn
LazyColumn
การจดจำท่าทางสัมผัสที่เฉพาะเจาะจง ฯลฯ คุณอาจพิจารณาต่อยอดจาก เลเยอร์พื้นฐานเพื่อสร้างระบบการออกแบบของคุณเอง - วัสดุ
- โมดูลนี้จะใช้ระบบ Material Design สำหรับ Compose UI โดยมีระบบการกำหนดธีม คอมโพเนนต์ที่มีสไตล์ การระบุการกระเพื่อม และไอคอน สร้างเลเยอร์นี้เมื่อใช้ Material Design ใน แอป
หลักการออกแบบ
หลักการชี้นำสำหรับ Jetpack Compose คือการมอบฟังก์ชันการทำงานขนาดเล็กที่มุ่งเน้นซึ่งสามารถประกอบ (หรือเขียน) ร่วมกันได้ แทนที่จะเป็นคอมโพเนนต์แบบโมโนลิธเพียงไม่กี่รายการ แนวทางนี้มีข้อดีหลายประการ
ควบคุม
คอมโพเนนต์ระดับสูงมักจะทำงานให้คุณมากขึ้น แต่จะจำกัดปริมาณการควบคุมโดยตรงที่คุณมี หากต้องการควบคุมมากขึ้น คุณสามารถ "เลื่อนลง" เพื่อใช้คอมโพเนนต์ระดับล่างได้
เช่น หากต้องการเปลี่ยนสีของคอมโพเนนต์ คุณอาจใช้ API
animateColorAsState
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
อย่างไรก็ตาม หากต้องการให้คอมโพเนนต์เริ่มต้นเป็นสีเทาเสมอ คุณจะทำไม่ได้ด้วย API นี้ แต่คุณสามารถใช้ API ระดับล่างได้โดยเลือกจากเมนูแบบเลื่อนลง
Animatable
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
API ระดับสูงกว่า animateColorAsState
สร้างขึ้นจาก API ระดับต่ำกว่า Animatable
การใช้ API ระดับล่างจะซับซ้อนกว่า แต่ให้การควบคุมได้มากกว่า
เลือกระดับการแยกข้อมูลที่เหมาะกับความต้องการของคุณมากที่สุด
การปรับแต่ง
การประกอบคอมโพเนนต์ระดับสูงจากบล็อกขนาดเล็กจะช่วยให้ปรับแต่งคอมโพเนนต์ได้ง่ายขึ้นมากหากจำเป็น ตัวอย่างเช่น ลองพิจารณาการติดตั้งใช้งาน
ของ
Button
ที่เลเยอร์ Material มีให้
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
Button
ประกอบด้วยคอมโพเนนต์ 4 อย่าง ได้แก่
Material
Surface
ที่ให้พื้นหลัง รูปร่าง การจัดการการคลิก ฯลฯA
CompositionLocalProvider
ซึ่งจะเปลี่ยนอัลฟ่าของเนื้อหาเมื่อเปิดหรือปิดใช้ปุ่มA
ProvideTextStyle
ตั้งค่ารูปแบบข้อความเริ่มต้นที่จะใช้Row
ระบุนโยบายเลย์เอาต์เริ่มต้นสำหรับเนื้อหาของปุ่ม
เราได้ละเว้นพารามิเตอร์และความคิดเห็นบางส่วนเพื่อให้โครงสร้างชัดเจนยิ่งขึ้น แต่
คอมโพเนนต์ทั้งหมดมีโค้ดเพียงประมาณ 40 บรรทัด เนื่องจากคอมโพเนนต์นี้เพียง
ประกอบคอมโพเนนต์ทั้ง 4 เพื่อใช้ปุ่ม คอมโพเนนต์ เช่น Button
มีแนวคิดเกี่ยวกับพารามิเตอร์ที่จะแสดง โดยจะพิจารณาถึงการเปิดใช้การปรับแต่งที่พบบ่อย
เทียบกับการเพิ่มพารามิเตอร์จำนวนมากซึ่งอาจทำให้คอมโพเนนต์
ใช้งานยากขึ้น เช่น คอมโพเนนต์ Material มีการปรับแต่งที่ระบุไว้
ในระบบ Material Design ซึ่งช่วยให้ปฏิบัติตามหลักการ
ของ Material Design ได้ง่าย
อย่างไรก็ตาม หากต้องการปรับแต่งนอกเหนือจากพารามิเตอร์ของคอมโพเนนต์
คุณสามารถ "ดร็อปดาวน์" ระดับและแยกคอมโพเนนต์ได้ เช่น Material
Design ระบุว่าปุ่มควรมีพื้นหลังสีทึบ หากต้องการพื้นหลังแบบไล่ระดับสี พารามิเตอร์ Button
จะไม่รองรับตัวเลือกนี้ ในกรณีนี้ คุณสามารถใช้การติดตั้งใช้งาน Material Button
เป็นข้อมูลอ้างอิงและสร้างคอมโพเนนต์ของคุณเองได้
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
การติดตั้งใช้งานข้างต้นยังคงใช้คอมโพเนนต์จากเลเยอร์ Material ต่อไป
เช่น แนวคิดของ Material เกี่ยวกับ
เนื้อหาปัจจุบัน (อัลฟ่า)
และรูปแบบข้อความปัจจุบัน แต่จะแทนที่วัสดุ Surface
ด้วย
Row
และจัดรูปแบบเพื่อให้ได้ลักษณะที่ต้องการ
หากไม่ต้องการใช้แนวคิด Material เลย เช่น หากสร้างระบบการออกแบบที่กำหนดเอง คุณก็เลือกใช้คอมโพเนนต์เลเยอร์พื้นฐานอย่างเดียวได้โดยทำดังนี้
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
Jetpack Compose จะสงวนชื่อที่ง่ายที่สุดไว้สำหรับคอมโพเนนต์ระดับสูงสุด เช่น
androidx.compose.material.Text
สร้างขึ้นบน
androidx.compose.foundation.text.BasicText
ซึ่งจะช่วยให้คุณสามารถใช้การติดตั้งใช้งานของคุณเองด้วยชื่อที่ค้นพบได้ง่ายที่สุด
หากต้องการแทนที่ระดับที่สูงกว่า
การเลือกการแยกส่วนที่เหมาะสม
ปรัชญาของ Compose ในการสร้างคอมโพเนนต์แบบเลเยอร์ที่นำกลับมาใช้ใหม่ได้หมายความว่าคุณไม่ควรใช้บล็อกการสร้างระดับล่างเสมอไป คอมโพเนนต์ระดับสูงหลายรายการไม่เพียงมีฟังก์ชันการทำงานที่มากขึ้น แต่ยังมักใช้แนวทางปฏิบัติแนะนำ เช่น การรองรับการช่วยเหลือพิเศษ
ตัวอย่างเช่น หากต้องการเพิ่มการรองรับท่าทางสัมผัสลงในคอมโพเนนต์ที่กำหนดเอง คุณ
สามารถสร้างคอมโพเนนต์นี้ตั้งแต่ต้นโดยใช้
Modifier.pointerInput
แต่ก็มีคอมโพเนนต์อื่นๆ ที่มีระดับสูงกว่าซึ่งสร้างขึ้นจากคอมโพเนนต์นี้ ซึ่งอาจ
เป็นจุดเริ่มต้นที่ดีกว่า เช่น
Modifier.draggable
,
Modifier.scrollable
หรือ Modifier.swipeable
โดยทั่วไปแล้ว เราขอแนะนำให้สร้างคอมโพเนนต์ระดับสูงสุดซึ่งมีฟังก์ชันการทำงานที่คุณต้องการเพื่อใช้ประโยชน์จากแนวทางปฏิบัติแนะนำที่คอมโพเนนต์นั้นมี
ดูข้อมูลเพิ่มเติม
ดูตัวอย่างการสร้างระบบการออกแบบที่กำหนดเองได้ที่ ตัวอย่าง Jetsnack
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- Kotlin สำหรับ Jetpack Compose
- รายการและตารางกริด
- ผลข้างเคียงในฟีเจอร์เขียน