1. ก่อนเริ่มต้น
Relay เป็นชุดเครื่องมือที่ช่วยให้ทีมออกแบบคอมโพเนนต์ UI ใน Figma และใช้คอมโพเนนต์เหล่านั้นในโปรเจ็กต์ Jetpack Compose ได้โดยตรง ซึ่งจะช่วยลดความซับซ้อนของข้อกำหนดการออกแบบและวงจร QA ซึ่งช่วยให้ทีมส่ง UI ของ Android ที่ยอดเยี่ยมได้อย่างรวดเร็ว
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีผสานรวมแพ็กเกจ UI ของ Relay เข้ากับกระบวนการพัฒนา Compose โดยมุ่งเน้นที่เทคนิคการผสานรวม ไม่ใช่เวิร์กโฟลว์ตั้งแต่ต้นจบ ดูข้อมูลเกี่ยวกับเวิร์กโฟลว์ทั่วไปของ Relay ได้ที่บทแนะนําเบื้องต้นเกี่ยวกับ Relay
ข้อกำหนดเบื้องต้น
- ประสบการณ์พื้นฐานในการใช้ Compose หากยังไม่ได้ทำ ให้ทำตาม Codelab พื้นฐานของ Jetpack Compose
- มีประสบการณ์เกี่ยวกับไวยากรณ์ Kotlin
สิ่งที่จะได้เรียนรู้
- วิธีนําเข้าแพ็กเกจ UI
- วิธีผสานรวมแพ็กเกจ UI กับการนําทางและสถาปัตยกรรมข้อมูล
- วิธีรวมแพ็กเกจ UI ด้วยตรรกะตัวควบคุม
- วิธีจับคู่สไตล์ Figma กับธีม Compose
- วิธีแทนที่แพ็กเกจ UI ด้วยคอมโพสิเบิลที่มีอยู่ในโค้ดที่สร้างขึ้น
สิ่งที่คุณจะสร้าง
- การออกแบบแอปที่เหมือนจริงโดยอิงตามแพ็กเกจ Relay ที่นักออกแบบให้มา แอปนี้มีชื่อว่า Reflect ซึ่งเป็นแอปติดตามรายวันที่ส่งเสริมสติและนิสัยที่ดี ซึ่งประกอบด้วยคอลเล็กชันเครื่องมือติดตามประเภทต่างๆ และ UI สำหรับเพิ่มและจัดการเครื่องมือติดตาม แอปมีลักษณะดังรูปภาพต่อไปนี้
สิ่งที่ต้องมี
- Android Studio Electric Eel ขึ้นไป
- บัญชี Figma ฟรีและโทเค็นการเข้าถึงส่วนบุคคล
2. ตั้งค่า
รับรหัส
หากต้องการดูโค้ดสําหรับโค้ดแล็บนี้ ให้ทําอย่างใดอย่างหนึ่งต่อไปนี้
- โคลนที่เก็บ
relay-codelabs
จาก GitHub
$ git clone https://github.com/googlecodelabs/relay-codelabs
- ไปที่ที่เก็บ
relay-codelabs
ใน GitHub เลือกสาขาที่ต้องการ แล้วคลิกโค้ด > ดาวน์โหลด ZIP จากนั้นแตกไฟล์ ZIP ที่ดาวน์โหลดมา
ไม่ว่าในกรณีใดก็ตาม สาขา main
จะมีโค้ดเริ่มต้นและสาขา end
จะมีโค้ดโซลูชัน
ติดตั้งปลั๊กอิน Relay สำหรับ Android Studio
หากยังไม่มีปลั๊กอิน Relay สำหรับ Android Studio ให้ทำตามขั้นตอนต่อไปนี้
- ใน Android Studio ให้คลิกการตั้งค่า > ปลั๊กอิน
- ป้อน
Relay for Android Studio
ในกล่องข้อความ - คลิกติดตั้งในส่วนขยายที่ปรากฏในผลการค้นหา
- หากเห็นกล่องโต้ตอบหมายเหตุเกี่ยวกับความเป็นส่วนตัวของปลั๊กอินของบุคคลที่สาม ให้คลิกยอมรับ
- คลิก OK > Restart
- หากเห็นกล่องโต้ตอบยืนยันการออก ให้คลิกออก
เชื่อมต่อ Android Studio กับ Figma
Relay จะดึงข้อมูลแพ็กเกจ UI ด้วย Figma API หากต้องการใช้ฟีเจอร์นี้ คุณต้องมีบัญชี Figma ฟรีและโทเค็นการเข้าถึงส่วนบุคคล จึงจะอยู่ในส่วนสิ่งที่ต้องมี
หากยังไม่ได้เชื่อมต่อ Android Studio กับ Figma ให้ทำตามขั้นตอนต่อไปนี้
- ในบัญชี Figma ให้คลิกไอคอนโปรไฟล์ที่ด้านบนของหน้า แล้วเลือกการตั้งค่า
- ในส่วนโทเค็นการเข้าถึงส่วนบุคคล ให้ป้อนคำอธิบายโทเค็นในกล่องข้อความ แล้วกด
Enter
(หรือreturn
ใน macOS) ระบบจะสร้างโทเค็น - คลิกคัดลอกโทเค็นนี้
- ใน Android Studio ให้เลือกเครื่องมือ > การตั้งค่ารีเลย์ กล่องโต้ตอบการตั้งค่ารีเลย์จะปรากฏขึ้น
- ในกล่องข้อความโทเค็นการเข้าถึง Figma ให้วางโทเค็นการเข้าถึง แล้วคลิก OK ตั้งค่าสภาพแวดล้อมแล้ว
3. ตรวจสอบการออกแบบของแอป
สำหรับแอป Reflect เราทำงานร่วมกับนักออกแบบเพื่อช่วยกำหนดสี การจัดวางตัวอักษร เลย์เอาต์ และลักษณะการทํางานของแอป เราออกแบบเหล่านี้ตามแบบแผนของ Material Design 3 เพื่อให้แอปทำงานร่วมกับคอมโพเนนต์และธีม Material ได้อย่างราบรื่น
ตรวจสอบหน้าจอหลัก
หน้าจอหลักจะแสดงรายการเครื่องมือติดตามที่ผู้ใช้กําหนด รวมถึงช่วยให้คุณเปลี่ยนวันที่มีการใช้งานและสร้างเครื่องมือติดตามอื่นๆ ได้ด้วย
ใน Figma นักออกแบบของเราแบ่งหน้าจอนี้ออกเป็นคอมโพเนนต์หลายรายการ กำหนด API ของคอมโพเนนต์เหล่านั้น และแพ็กเกจไว้กับปลั๊กอิน Relay สำหรับ Figma หลังจากแพ็กเกจคอมโพเนนต์เหล่านี้แล้ว คุณจะนําเข้าคอมโพเนนต์เหล่านั้นไปยังโปรเจ็กต์ Android Studio ได้
ตรวจสอบหน้าจอเพิ่ม/แก้ไข
หน้าจอเพิ่ม/แก้ไขช่วยให้ผู้ใช้เพิ่มหรือแก้ไขอุปกรณ์ติดตามได้ รูปแบบที่แสดงจะแตกต่างกันเล็กน้อยตามประเภทเครื่องมือติดตาม
ในทํานองเดียวกัน หน้าจอนี้จะแบ่งออกเป็นคอมโพเนนต์ที่แพ็กเกจไว้หลายรายการ
ตรวจสอบธีม
สีและแบบอักษรของการออกแบบนี้ใช้รูปแบบ Figma ตามชื่อโทเค็นของ Material Design 3 ซึ่งจะช่วยให้ทำงานร่วมกันกับธีม Compose และ Material Components ได้ดียิ่งขึ้น
4. นําเข้าแพ็กเกจ UI
รับลิงก์ไปยังแหล่งที่มาของ Figma
คุณต้องอัปโหลดแหล่งที่มาของการออกแบบไปยัง Figma ก่อนจึงจะนําเข้าแพ็กเกจ UI ไปยังโปรเจ็กต์ได้
หากต้องการดูลิงก์ไปยังแหล่งที่มาของ Figma ให้ทำตามขั้นตอนต่อไปนี้
- ใน Figma ให้คลิกนําเข้าไฟล์ แล้วเลือกไฟล์
ReflectDesign.fig
ที่พบในโฟลเดอร์โปรเจ็กต์CompleteAppCodelab
- คลิกขวาที่ไฟล์ แล้วเลือกคัดลอกลิงก์ ซึ่งจะต้องใช้ในส่วนถัดไป
นําเข้าแพ็กเกจ UI ไปยังโปรเจ็กต์
- เปิดโปรเจ็กต์
./CompleteAppCodelab
ใน Android Studio - คลิก File > New > Import UI Packages กล่องโต้ตอบนําเข้าแพ็กเกจ UI จะปรากฏขึ้น
- วาง URL ที่คัดลอกไว้ในส่วนก่อนหน้าในกล่องข้อความ URL แหล่งที่มาของ Figma
- ในกล่องข้อความธีมแอป ให้ป้อน
com.google.relay.example.reflect.ui.theme.ReflectTheme
วิธีนี้ช่วยให้มั่นใจว่าตัวอย่างเพลงที่สร้างขึ้นจะใช้ธีมที่กำหนดเอง - คลิกถัดไป คุณจะเห็นตัวอย่างแพ็กเกจ UI ของไฟล์
- คลิกสร้าง ระบบจะนำเข้าแพ็กเกจไปยังโปรเจ็กต์
- ไปที่แท็บโปรเจ็กต์ แล้วคลิกลูกศรขยาย
ข้างโฟลเดอร์
ui-packages
- คลิก
ลูกศรขยายข้างโฟลเดอร์แพ็กเกจ แล้วสังเกตว่ามีไฟล์ต้นฉบับ
JSON
และทรัพยากรที่เกี่ยวข้อง - เปิดไฟล์ต้นฉบับ
JSON
โมดูล Relay จะแสดงตัวอย่างของแพ็กเกจและ API ของแพ็กเกจ
สร้างและสร้างโค้ด
- ที่ด้านบนของ Android Studio ให้คลิก
สร้างโปรเจ็กต์ ระบบจะเพิ่มโค้ดที่สร้างขึ้นสำหรับแต่ละแพ็กเกจลงในโฟลเดอร์
java/com.google.relay.example.reflect
คอมโพสิชันที่สร้างขึ้นจะมีข้อมูลเลย์เอาต์และการจัดรูปแบบทั้งหมดจากการออกแบบใน Figma - เปิดไฟล์
com/google/relay/example/reflect/range/Range.kt
- โปรดทราบว่าระบบจะสร้างตัวอย่างการคอมโพสิทสำหรับคอมโพเนนต์แต่ละรูปแบบ หากจำเป็น ให้คลิกแยกเพื่อให้เห็นแผงรหัสและแผงแสดงตัวอย่างอยู่ข้างกัน
5. ผสานรวมคอมโพเนนต์
ในส่วนนี้ คุณจะเห็นรายละเอียดของโค้ดที่สร้างขึ้นสําหรับเครื่องมือติดตาม Switch
- เปิดไฟล์
com/google/relay/example/reflect/switch/Switch.kt
ใน Android Studio
Switch.kt (สร้างขึ้น)
/**
* This composable was generated from the UI Package 'switch'.
* Generated code; don't edit directly.
*/
@Composable
fun Switch(
modifier: Modifier = Modifier,
isChecked: Boolean = false,
emoji: String = "",
title: String = ""
) {
TopLevel(modifier = modifier) {
if (isChecked) {
ActiveOverlay(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)) {}
}
TopLevelSynth(modifier = Modifier.rowWeight(1.0f)) {
Label(modifier = Modifier.rowWeight(1.0f)) {
Emoji(emoji = emoji)
Title(
title = title,
modifier = Modifier.rowWeight(1.0f)
)
}
Checkmark {
if (isChecked) {
Icon()
}
}
}
}
}
- โปรดสังเกตสิ่งต่อไปนี้
- ระบบจะสร้างเลย์เอาต์และการจัดสไตล์ทั้งหมดจากการออกแบบใน Figma
- องค์ประกอบย่อยจะแบ่งออกเป็นคอมโพสิเบิลแยกกัน
- ระบบจะสร้างตัวอย่างแบบคอมโพสได้สำหรับรูปแบบการออกแบบทั้งหมด
- รูปแบบสีและแบบอักษรเป็นแบบฮาร์ดโค้ด คุณแก้ไขเรื่องนี้ในภายหลังได้
แทรกอุปกรณ์ติดตาม
- เปิดไฟล์
java/com/google/relay/example/reflect/ui/components/TrackerControl.kt
ใน Android Studio ไฟล์นี้จะให้ข้อมูลและตรรกะการโต้ตอบแก่เครื่องมือติดตามพฤติกรรม - สร้างและเรียกใช้แอปในโปรแกรมจำลอง ปัจจุบันคอมโพเนนต์นี้จะแสดงผลข้อมูลดิบจากรุ่นอุปกรณ์ติดตาม
- นําเข้าแพ็กเกจ
com.google.relay.example.reflect.switch.Switch
ไปยังไฟล์ - แทนที่
Text(text = trackerData.tracker.toString())
ด้วยบล็อกwhen
ที่วางแนวในช่องtrackerData.tracker.type
- ในเนื้อหาของบล็อก
when
ให้เรียกใช้ฟังก์ชันSwitch()
Composable
เมื่อประเภทเป็นTrackerType.BOOLEAN
โค้ดของคุณควรมีลักษณะดังนี้
TrackerControl.kt
// TODO: replace with Relay tracker components
when (trackerData.tracker.type) {
TrackerType.BOOLEAN ->
Switch(
title = trackerData.tracker.name,
emoji = trackerData.tracker.emoji
)
else ->
Text(trackerData.tracker.toString())
}
- สร้างโปรเจ็กต์อีกครั้ง ตอนนี้หน้าแรกแสดงผลเครื่องมือติดตาม Switch อย่างถูกต้องตามที่ออกแบบไว้ด้วยข้อมูลสด
6. เพิ่มสถานะและการโต้ตอบ
แพ็กเกจ UI เป็นแบบไม่มีสถานะ สิ่งที่แสดงผลคือผลลัพธ์ง่ายๆ ของพารามิเตอร์ที่ส่งเข้ามา แต่แอปจริงต้องมีการโต้ตอบและสถานะ แฮนเดิลการโต้ตอบสามารถส่งไปยังคอมโพสิเบิลที่สร้างขึ้นได้เช่นเดียวกับพารามิเตอร์อื่นๆ แต่คุณจะเก็บสถานะที่ตัวแฮนเดิลเหล่านั้นจัดการไว้ที่ใด คุณจะหลีกเลี่ยงการส่งตัวแฮนเดิลเดียวกันไปยังอินสแตนซ์ทุกรายการได้อย่างไร คุณจะทำให้การคอมโพสแพ็กเกจเป็นคอมโพสิเบิลที่นำมาใช้ซ้ำได้ได้อย่างไร สำหรับกรณีเหล่านี้ เราขอแนะนำให้คุณรวมแพ็กเกจที่สร้างขึ้นไว้ในฟังก์ชัน Composable
ที่กำหนดเอง
ตัดแพ็กเกจ UI ในฟังก์ชัน Composable
ของตัวควบคุม
การรวมแพ็กเกจ UI ในฟังก์ชัน Composable
ของตัวควบคุมช่วยให้คุณปรับแต่งการแสดงผลหรือตรรกะทางธุรกิจ และจัดการสถานะในเครื่องได้ (หากจำเป็น) นักออกแบบจะยังคงอัปเดตแพ็กเกจ UI เดิมใน Figma ได้โดยไม่ต้องอัปเดตโค้ด Wrapper
หากต้องการสร้างตัวควบคุมสำหรับอุปกรณ์ติดตาม Switch ให้ทำตามขั้นตอนต่อไปนี้
- เปิดไฟล์
java/com/google/relay/example/reflect/ui/components/SwitchControl.kt
ใน Android Studio - ในฟังก์ชัน
SwitchControl()
Composable
ให้ส่งพารามิเตอร์ต่อไปนี้
trackerData
: ออบเจ็กต์TrackerData
modifier
: ออบเจ็กต์ตัวตกแต่งonLongClick
: การเรียกกลับการโต้ตอบเพื่อเปิดใช้การกดติดตามค้างไว้เพื่อแก้ไขและลบ
- แทรกฟังก์ชัน
Switch()
และส่งตัวแก้ไขcombinedClickable
เพื่อจัดการการคลิกและการกดค้าง - ส่งค่าจากออบเจ็กต์
TrackerData
ไปยังฟังก์ชันSwitch()
รวมถึงเมธอดisToggled()
ฟังก์ชัน SwitchControl()
ที่เสร็จสมบูรณ์จะมีลักษณะเป็นข้อมูลโค้ดต่อไปนี้
SwitchControl.kt
package com.google.relay.example.reflect.ui.components
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.relay.example.reflect.model.Tracker
import com.google.relay.example.reflect.model.TrackerData
import com.google.relay.example.reflect.model.TrackerType
import com.google.relay.example.reflect.switch.Switch
/*
* A component for controlling switch-type trackers.
*
* SwitchControl is responsible for providing interaction and state management to the stateless
* composable [Switch] generated by Relay. [onLongClick] provides a way for callers to supplement
* the control's intrinsic interactions with, for example, a context menu.
*/
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SwitchControl(
trackerData: TrackerData,
modifier: Modifier = Modifier,
onLongClick: (() -> Unit)? = null,
) {
Switch(
modifier
.clip(shape = RoundedCornerShape(size = 32.dp))
.combinedClickable(onLongClick = onLongClick) {
trackerData.toggle()
},
emoji = trackerData.tracker.emoji,
title = trackerData.tracker.name,
isChecked = trackerData.isToggled(),
)
}
@Preview
@Composable
fun SwitchControllerPreview() {
val data = TrackerData(
Tracker(
emoji = "🍕",
name = "Ate Pizza",
type = TrackerType.BOOLEAN
)
)
SwitchControl(data)
}
- ในไฟล์
TrackerControl.kt
ให้นําการนําเข้าSwitch
ออก แล้วแทนที่ฟังก์ชันSwitch()
ด้วยการเรียกใช้ฟังก์ชันSwitchControl()
- เพิ่มกรณีสำหรับค่าคงที่ตัวระบุรายการ
TrackerType.RANGE
และTrackerType.COUNT
บล็อก when
ที่เสร็จสมบูรณ์จะมีลักษณะเป็นข้อมูลโค้ดต่อไปนี้
TrackerControl.kt
when (trackerData.tracker.type) {
TrackerType.BOOLEAN ->
SwitchControl(
trackerData = trackerData,
onLongClick = { expanded = true },
)
TrackerType.RANGE ->
RangeControl(
trackerData = trackerData,
onLongClick = { expanded = true },
)
TrackerType.COUNT ->
ValueControl(
trackerData = trackerData,
onLongClick = { expanded = true },
)
}
- สร้างโปรเจ็กต์อีกครั้ง ตอนนี้คุณแสดงและโต้ตอบกับอุปกรณ์ติดตามได้แล้ว หน้าจอหลักเสร็จสมบูรณ์
7. แมปคอมโพเนนต์ที่มีอยู่
Relay ช่วยให้นักพัฒนาซอฟต์แวร์ปรับแต่งโค้ดที่สร้างขึ้นได้โดยแทนที่แพ็กเกจ UI ด้วยคอมโพสิเบิลที่มีอยู่ วิธีนี้เป็นวิธีที่ยอดเยี่ยมในการแสดงผลคอมโพเนนต์ที่พร้อมใช้งานหรือแม้แต่ระบบการออกแบบที่กำหนดเองในโค้ด
แมปช่องข้อความ
รูปภาพต่อไปนี้เป็นการออกแบบคอมโพเนนต์ Tracker Settings
ในกล่องโต้ตอบเพิ่ม/แก้ไขเครื่องมือติดตาม
นักออกแบบของเราใช้ ReflectTextField
ในการออกแบบ ซึ่งเรามีการใช้งานในโค้ดที่สร้างขึ้นจากช่องข้อความ Material Design 3 อยู่แล้ว Figma ไม่รองรับช่องข้อความโดยกำเนิด ดังนั้นโค้ดเริ่มต้นที่ Relay สร้างขึ้นจึงมีหน้าตาเหมือนกับการออกแบบเท่านั้น ไม่ใช่การควบคุมที่ใช้งานได้
วิธีทดสอบการใช้งานปัจจุบันสําหรับ TrackerSettings
- ใน Android Studio ให้สร้างและเรียกใช้แอปในโปรแกรมจำลอง
- กดแถวอุปกรณ์ติดตามค้างไว้ แล้วเลือกแก้ไข
- แตะช่องข้อความ
Title
และสังเกตว่าช่องไม่ตอบสนองต่อการโต้ตอบ
หากต้องการแทนที่การติดตั้งใช้งานจริงสําหรับองค์ประกอบนี้ คุณต้องมี 2 อย่าง ได้แก่ แพ็กเกจ UI ของช่องข้อความและไฟล์การแมป แต่โชคดีที่นักออกแบบของเราได้แพ็กเกจคอมโพเนนต์ระบบการออกแบบใน Figma ไว้แล้วและใช้คอมโพเนนต์ช่องข้อความในการออกแบบสำหรับ Tracker Settings
โดยค่าเริ่มต้น ระบบจะสร้างแพ็กเกจที่ฝังนี้ขึ้นเป็นข้อกำหนด แต่คุณใช้การแมปคอมโพเนนต์เพื่อเปลี่ยนแพ็กเกจได้
สร้างไฟล์การแมป
ปลั๊กอิน Relay สำหรับ Android Studio มีทางลัดสำหรับสร้างไฟล์การแมปคอมโพเนนต์
หากต้องการสร้างไฟล์การแมป ให้ทําตามขั้นตอนต่อไปนี้
- ใน Android Studio ให้คลิกขวาที่แพ็กเกจ UI
text_field
แล้วเลือกสร้างไฟล์การแมป
- กล่องโต้ตอบไฟล์การแมปจะปรากฏขึ้น ป้อนตัวเลือกต่อไปนี้
- ในคอมโพสิเบิลเป้าหมาย ให้เลือกใช้คอมโพสิเบิลที่มีอยู่ แล้วป้อน
com.google.relay.example.reflect.ui.components.ReflectTextField
- ในไฟล์ที่สร้างขึ้น ให้เลือกสร้างการใช้งานและยกเลิกการเลือกสร้างตัวอย่างการคอมโพส
- คลิกสร้างไฟล์การแมป ซึ่งจะสร้างไฟล์การแมปต่อไปนี้
text_field.json
{
"target": "ReflectTextField",
"package": "com.google.relay.example.reflect.ui.components",
"generateImplementation": true,
"generatePreviews": false,
}
ไฟล์การแมปคอมโพเนนต์จะระบุเป้าหมายและแพ็กเกจคลาส Compose รวมถึงคอลเล็กชันออบเจ็กต์ fieldMapping
ที่ไม่บังคับ การแมปช่องเหล่านี้ช่วยให้คุณเปลี่ยนพารามิเตอร์แพ็กเกจให้เป็นพารามิเตอร์ Compose ที่คาดไว้ได้ ในกรณีนี้ API จะเหมือนกัน คุณจึงต้องระบุเฉพาะคลาสเป้าหมายเท่านั้น
- สร้างโปรเจ็กต์อีกครั้ง
- ในไฟล์
trackersettings/
TrackerSettings.kt
ให้ค้นหาฟังก์ชันTitleFieldStyleFilledStateEnabledTextConfigurationsInputText()
Composable ที่สร้างขึ้น และสังเกตว่ามีคอมโพเนนต์ReflectTextField
ที่สร้างขึ้น
TrackerSettings.kt (generated)
@Composable
fun TitleFieldStyleFilledStateEnabledTextConfigurationsInputText(
onTitleChanged: (String) -> Unit,
title: String,
modifier: Modifier = Modifier
) {
ReflectTextField(
onChange = onTitleChanged,
labelText = "Title",
leadingIcon = "search",
trailingIcon = "cancel",
supportingText = "Supporting text",
inputText = title,
state = State.Enabled,
textConfigurations = TextConfigurations.InputText,
modifier = modifier.fillMaxWidth(1.0f).requiredHeight(56.0.dp)
)
}
- สร้างโปรเจ็กต์อีกครั้ง ตอนนี้คุณสามารถโต้ตอบกับช่องการตั้งค่าอุปกรณ์ติดตามได้แล้ว หน้าจอแก้ไขเสร็จสมบูรณ์
8. แมปกับธีม Compose
โดยค่าเริ่มต้น Relay จะสร้างค่าตัวอักษรล้วนสำหรับสีและการจัดรูปแบบตัวอักษร วิธีนี้ช่วยให้มั่นใจได้ว่าคำแปลจะถูกต้อง แต่ป้องกันไม่ให้คอมโพเนนต์ใช้ระบบธีมของ Compose คุณจะเห็นได้ชัดเมื่อดูแอปในโหมดมืด
คอมโพเนนต์การนําทางวันแทบมองไม่เห็นและสีไม่ถูกต้อง วิธีแก้ปัญหานี้คือให้ใช้ฟีเจอร์การแมปสไตล์ใน Relay เพื่อลิงก์สไตล์ Figma กับโทนสีของ Compose ในโค้ดที่สร้างขึ้น ซึ่งจะช่วยเพิ่มความสอดคล้องของภาพระหว่าง Relay กับคอมโพเนนต์ Material Design 3 และเปิดใช้การรองรับโหมดมืด
สร้างไฟล์การแมปสไตล์
- ใน Android Studio ให้ไปที่ไดเรกทอรี
src/main/ui-package-resources
แล้วสร้างไดเรกทอรีใหม่ชื่อstyle-mappings
ในไดเรกทอรีดังกล่าว ให้สร้างไฟล์figma_styles.json
ที่มีโค้ดต่อไปนี้
figma_styles.json
{
"figma": {
"colors": {
"Reflect Light/background": "md.sys.color.background",
"Reflect Dark/background": "md.sys.color.background",
"Reflect Light/on-background": "md.sys.color.on-background",
"Reflect Dark/on-background": "md.sys.color.on-background",
"Reflect Light/surface": "md.sys.color.surface",
"Reflect Dark/surface": "md.sys.color.surface",
"Reflect Light/on-surface": "md.sys.color.on-surface",
"Reflect Dark/on-surface": "md.sys.color.on-surface",
"Reflect Light/surface-variant": "md.sys.color.surface-variant",
"Reflect Dark/surface-variant": "md.sys.color.surface-variant",
"Reflect Light/on-surface-variant": "md.sys.color.on-surface-variant",
"Reflect Dark/on-surface-variant": "md.sys.color.on-surface-variant",
"Reflect Light/primary": "md.sys.color.primary",
"Reflect Dark/primary": "md.sys.color.primary",
"Reflect Light/on-primary": "md.sys.color.on-primary",
"Reflect Dark/on-primary": "md.sys.color.on-primary",
"Reflect Light/primary-container": "md.sys.color.primary-container",
"Reflect Dark/primary-container": "md.sys.color.primary-container",
"Reflect Light/on-primary-container": "md.sys.color.on-primary-container",
"Reflect Dark/on-primary-container": "md.sys.color.on-primary-container",
"Reflect Light/secondary-container": "md.sys.color.secondary-container",
"Reflect Dark/secondary-container": "md.sys.color.secondary-container",
"Reflect Light/on-secondary-container": "md.sys.color.on-secondary-container",
"Reflect Dark/on-secondary-container": "md.sys.color.on-secondary-container",
"Reflect Light/outline": "md.sys.color.outline",
"Reflect Dark/outline": "md.sys.color.outline",
"Reflect Light/error": "md.sys.color.error",
"Reflect Dark/error": "md.sys.color.error"
},
"typography": {
"symbols": {
"Reflect/headline/large": "md.sys.typescale.headline-large",
"Reflect/headline/medium": "md.sys.typescale.headline-medium",
"Reflect/headline/small": "md.sys.typescale.headline-small",
"Reflect/title/large": "md.sys.typescale.title-large",
"Reflect/title/medium": "md.sys.typescale.title-medium",
"Reflect/title/small": "md.sys.typescale.title-small",
"Reflect/body/large": "md.sys.typescale.body-large",
"Reflect/body/medium": "md.sys.typescale.body-medium",
"Reflect/body/small": "md.sys.typescale.body-small",
"Reflect/label/large": "md.sys.typescale.label-large",
"Reflect/label/medium": "md.sys.typescale.label-medium",
"Reflect/label/small": "md.sys.typescale.label-small"
},
"subproperties": {
"fontFamily": "font",
"fontWeight": "weight",
"fontSize": "size",
"letterSpacing": "tracking",
"lineHeightPx": "line-height"
}
}
},
"compose": {
"colors": {
"md.sys.color.background": "MaterialTheme.colorScheme.background",
"md.sys.color.error": "MaterialTheme.colorScheme.error",
"md.sys.color.error-container": "MaterialTheme.colorScheme.errorContainer",
"md.sys.color.inverse-on-surface": "MaterialTheme.colorScheme.inverseOnSurface",
"md.sys.color.inverse-surface": "MaterialTheme.colorScheme.inverseSurface",
"md.sys.color.on-background": "MaterialTheme.colorScheme.onBackground",
"md.sys.color.on-error": "MaterialTheme.colorScheme.onError",
"md.sys.color.on-error-container": "MaterialTheme.colorScheme.onErrorContainer",
"md.sys.color.on-primary": "MaterialTheme.colorScheme.onPrimary",
"md.sys.color.on-primary-container": "MaterialTheme.colorScheme.onPrimaryContainer",
"md.sys.color.on-secondary": "MaterialTheme.colorScheme.onSecondary",
"md.sys.color.on-secondary-container": "MaterialTheme.colorScheme.onSecondaryContainer",
"md.sys.color.on-surface": "MaterialTheme.colorScheme.onSurface",
"md.sys.color.on-surface-variant": "MaterialTheme.colorScheme.onSurfaceVariant",
"md.sys.color.on-tertiary": "MaterialTheme.colorScheme.onTertiary",
"md.sys.color.on-tertiary-container": "MaterialTheme.colorScheme.onTertiaryContainer",
"md.sys.color.outline": "MaterialTheme.colorScheme.outline",
"md.sys.color.primary": "MaterialTheme.colorScheme.primary",
"md.sys.color.primary-container": "MaterialTheme.colorScheme.primaryContainer",
"md.sys.color.secondary": "MaterialTheme.colorScheme.secondary",
"md.sys.color.secondary-container": "MaterialTheme.colorScheme.secondaryContainer",
"md.sys.color.surface": "MaterialTheme.colorScheme.surface",
"md.sys.color.surface-variant": "MaterialTheme.colorScheme.surfaceVariant",
"md.sys.color.tertiary": "MaterialTheme.colorScheme.tertiary",
"md.sys.color.tertiary-container": "MaterialTheme.colorScheme.tertiaryContainer"
},
"typography": {
"symbols": {
"md.sys.typescale.display-large": "MaterialTheme.typography.displayLarge",
"md.sys.typescale.display-medium": "MaterialTheme.typography.displayMedium",
"md.sys.typescale.display-small": "MaterialTheme.typography.displaySmall",
"md.sys.typescale.headline-large": "MaterialTheme.typography.headlineLarge",
"md.sys.typescale.headline-medium": "MaterialTheme.typography.headlineMedium",
"md.sys.typescale.headline-small": "MaterialTheme.typography.headlineSmall",
"md.sys.typescale.title-large": "MaterialTheme.typography.titleLarge",
"md.sys.typescale.title-medium": "MaterialTheme.typography.titleMedium",
"md.sys.typescale.title-small": "MaterialTheme.typography.titleSmall",
"md.sys.typescale.body-large": "MaterialTheme.typography.bodyLarge",
"md.sys.typescale.body-medium": "MaterialTheme.typography.bodyMedium",
"md.sys.typescale.body-small": "MaterialTheme.typography.bodySmall",
"md.sys.typescale.label-large": "MaterialTheme.typography.labelLarge",
"md.sys.typescale.label-medium": "MaterialTheme.typography.labelMedium",
"md.sys.typescale.label-small": "MaterialTheme.typography.labelSmall"
},
"subproperties": {
"font": "fontFamily",
"weight": "fontWeight",
"size": "fontSize",
"tracking": "letterSpacing",
"line-height": "lineHeight"
}
},
"options": {
"packages": {
"MaterialTheme": "androidx.compose.material3"
}
}
}
}
ไฟล์การแมปธีมมีโครงสร้างที่มีออบเจ็กต์ระดับบนสุด 2 รายการ ได้แก่ figma
และ compose
ภายในออบเจ็กต์เหล่านี้ คำจำกัดความของสีและประเภทจะลิงก์กันระหว่าง 2 สภาพแวดล้อมผ่านโทเค็นกลาง ซึ่งช่วยให้สไตล์ Figma หลายสไตล์แมปกับรายการธีม Compose รายการเดียวได้ ซึ่งจะมีประโยชน์เมื่อคุณรองรับธีมสว่างและธีมมืด
- ตรวจสอบไฟล์การแมป โดยเฉพาะอย่างยิ่งวิธีแมปพร็อพเพอร์ตี้แบบอักษรจาก Figma ไปยังสิ่งที่ Compose คาดหวัง
นําเข้าแพ็กเกจ UI อีกครั้ง
หลังจากสร้างไฟล์การแมปแล้ว คุณต้องนําเข้าแพ็กเกจ UI ทั้งหมดกลับไปยังโปรเจ็กต์อีกครั้ง เนื่องจากระบบจะทิ้งค่าสไตล์ Figma ทั้งหมดเมื่อนําเข้าครั้งแรกเนื่องจากไม่มีไฟล์การแมป
หากต้องการนําเข้าแพ็กเกจ UI อีกครั้ง ให้ทําตามขั้นตอนต่อไปนี้
- ใน Android Studio ให้คลิกไฟล์ > ใหม่ > นําเข้าแพ็กเกจ UI กล่องโต้ตอบนําเข้าแพ็กเกจ UI จะปรากฏขึ้น
- ในกล่องข้อความ URL แหล่งที่มาของ Figma ให้ป้อน URL ของไฟล์ต้นทาง Figma
- เลือกช่องทำเครื่องหมายแปลสไตล์ Figma เป็นธีม Compose
- เลือกนําเข้าการกําหนดค่าที่กําหนดเอง คลิกไอคอนโฟลเดอร์ แล้วเลือกไฟล์ที่คุณเพิ่งสร้าง
src/main/ui-package-resources/style-mappings/figma_styles.json
- คลิกถัดไป คุณจะเห็นตัวอย่างแพ็กเกจ UI ของไฟล์
- คลิกสร้าง ระบบจะนำเข้าแพ็กเกจไปยังโปรเจ็กต์
- โปรดสร้างโปรเจ็กต์อีกครั้ง แล้วเปิดไฟล์
switch/Switch.kt
เพื่อดูโค้ดที่สร้างขึ้น
Switch.kt (สร้างขึ้น)
@Composable
fun ActiveOverlay(
modifier: Modifier = Modifier,
content: @Composable RelayContainerScope.() -> Unit
) {
RelayContainer(
backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
isStructured = false,
radius = 32.0,
content = content,
modifier = modifier.fillMaxWidth(1.0f).fillMaxHeight(1.0f)
)
}
- สังเกตว่ามีการกําหนดค่าพารามิเตอร์
backgroundColor
เป็นช่องMaterialTheme.colorScheme.surfaceVariant
อย่างไรในออบเจ็กต์ธีมการเขียน - เรียกใช้โปรเจ็กต์และเปิดโหมดมืดในโปรแกรมจำลอง ธีมมีผลอย่างถูกต้องและข้อบกพร่องด้านภาพได้รับการแก้ไขแล้ว
9. ขอแสดงความยินดี
ยินดีด้วย คุณได้เรียนรู้วิธีผสานรวม Relay เข้ากับแอป Compose แล้ว