หน้านี้ให้ภาพรวมระดับสูงของเลเยอร์สถาปัตยกรรมที่ประกอบกันเป็น 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 - มูลนิธิ
- โมดูลนี้มีบล็อกการสร้างที่ไม่ขึ้นอยู่กับระบบการออกแบบสำหรับ UI ของ Compose
เช่น
Row
และColumn
LazyColumn
การจดจำท่าทางสัมผัสที่เฉพาะเจาะจง ฯลฯ คุณอาจพิจารณาต่อยอดจาก เลเยอร์พื้นฐานเพื่อสร้างระบบการออกแบบของคุณเอง - วัสดุ
- โมดูลนี้จะใช้ระบบ Material Design สำหรับ Compose UI โดยมีระบบการกำหนดธีม คอมโพเนนต์ที่มีสไตล์ การระบุการกระเพื่อม และไอคอน สร้างเลเยอร์นี้เมื่อใช้ Material Design ใน แอป
หลักการออกแบบ
หลักการชี้นำสำหรับ Jetpack Compose คือการมอบฟังก์ชันการทำงานขนาดเล็กที่มุ่งเน้น ซึ่งสามารถประกอบ (หรือ 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
- รายการและตารางกริด
- ผลข้างเคียงในฟีเจอร์เขียน