ดูตัวอย่าง UI ด้วยตัวอย่างที่เขียนได้ด้วย Compose

Composable จะกำหนดโดยฟังก์ชันและมีคำอธิบายประกอบด้วย @Composable ดังนี้

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

องค์ประกอบของข้อความธรรมดาที่มีคำว่า "Hello
World"

หากต้องการเปิดใช้ตัวอย่างของ Composable นี้ ให้สร้าง Composable อีกรายการหนึ่งที่มีคำอธิบายประกอบด้วย @Composable และ @Preview ตอนนี้ Composable ใหม่ที่มีคำอธิบายประกอบนี้จะมี Composable ที่คุณสร้างขึ้นในตอนแรก ซึ่งก็คือ SimpleComposable

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

คำอธิบายประกอบ @Preview จะบอก Android Studio ว่า Composable นี้ควรแสดงในมุมมองการออกแบบของไฟล์นี้ คุณจะเห็นการอัปเดตตัวอย่าง Composable แบบเรียลไทม์ขณะทำการแก้ไข

GIF แสดงการอัปเดตแบบเรียลไทม์โดยใช้ Compose
Preview

คุณสามารถเพิ่มพารามิเตอร์ลงในโค้ดด้วยตนเองเพื่อปรับแต่งวิธีที่ Android Studio แสดงผล @Preview หรือจะเพิ่มคำอธิบายประกอบ @Preview ลงในฟังก์ชันเดียวกันหลายครั้งเพื่อดูตัวอย่าง Composable ที่มีพร็อพเพอร์ตี้ต่างๆ ก็ได้

ข้อดีหลักอย่างหนึ่งของการใช้ Composable @Preview คือการหลีกเลี่ยงการพึ่งพาโปรแกรมจำลองใน Android Studio คุณสามารถบันทึกการเริ่มต้นโปรแกรมจำลองที่ใช้หน่วยความจำมากไว้สำหรับการเปลี่ยนแปลงรูปลักษณ์ขั้นสุดท้าย และใช้ความสามารถของ @Preview ในการทำการเปลี่ยนแปลงโค้ดเล็กๆ น้อยๆ และทดสอบได้อย่างง่ายดาย

หากต้องการใช้ประโยชน์จากคำอธิบายประกอบ @Preview ได้อย่างมีประสิทธิภาพสูงสุด ให้กำหนดหน้าจอในแง่ของสถานะที่ได้รับเป็นอินพุตและเหตุการณ์ที่ส่งออก

กำหนด @Preview

Android Studio มีฟีเจอร์บางอย่างเพื่อขยายตัวอย่าง Composable คุณสามารถเปลี่ยนการออกแบบคอนเทนเนอร์ โต้ตอบกับตัวอย่าง หรือทำให้ใช้งานได้กับโปรแกรมจำลองหรืออุปกรณ์โดยตรง

ขนาด

โดยค่าเริ่มต้น ระบบจะเลือกขนาด @Preview โดยอัตโนมัติเพื่อให้พอดีกับเนื้อหา หากต้องการตั้งค่าขนาดด้วยตนเอง ให้เพิ่มพารามิเตอร์ heightDp และ widthDp ระบบจะตีความค่าเหล่านั้นเป็น dp อยู่แล้ว คุณจึงไม่จำเป็นต้องเพิ่ม .dpลงในค่าเหล่านั้น

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

สี่เหลี่ยมสีเหลืองที่มีคำว่า "Hello
World"

ตัวอย่างสีแบบไดนามิก

หากเปิดใช้ สีแบบไดนามิกในแอป ให้ใช้แอตทริบิวต์ wallpaper เพื่อเปลี่ยนวอลเปเปอร์และดูว่า UI ตอบสนองต่อวอลเปเปอร์ที่ผู้ใช้แต่ละรายเลือกอย่างไร เลือกจากธีมวอลเปเปอร์ต่างๆ ที่ Wallpaper คลาสมีให้ ฟีเจอร์นี้ต้องใช้ Compose 1.4.0 ขึ้นไป

ใช้กับอุปกรณ์ต่างๆ

ใน Android Studio Flamingo คุณสามารถแก้ไขพารามิเตอร์ device ของคำอธิบายประกอบ Preview เพื่อกำหนดการกำหนดค่าสำหรับ Composable ในอุปกรณ์ต่างๆ ได้

ตัวอย่างฟังก์ชันที่ประกอบกันได้

เมื่อพารามิเตอร์ device มีสตริงว่าง (@Preview(device = "")) คุณสามารถ เรียกใช้การเติมข้อความอัตโนมัติได้โดยกด Ctrl + Space จากนั้นคุณจะตั้งค่าพารามิเตอร์แต่ละรายการได้

การแก้ไขฟังก์ชัน
ตัวอย่าง

จากการเติมข้อความอัตโนมัติ คุณสามารถเลือกตัวเลือกอุปกรณ์ใดก็ได้จากรายการ เช่น @Preview(device = "id:pixel_4") หรือจะป้อนอุปกรณ์ที่กำหนดเองโดยเลือก spec:width=px,height=px,dpi=int… เพื่อตั้งค่าแต่ละค่าของพารามิเตอร์แต่ละรายการก็ได้

ข้อมูลจำเพาะ
รายการ

หากต้องการใช้ ให้กด Enter หรือยกเลิกด้วย Esc

หากตั้งค่าที่ไม่ถูกต้อง ระบบจะขีดเส้นใต้การประกาศเป็นสีแดง และอาจมีการแก้ไขให้ ได้ (Alt + Enter (⌥ + ⏎ สำหรับ macOS) > Replace with … การตรวจสอบจะพยายามแก้ไขให้ใกล้เคียงกับอินพุตของคุณมากที่สุด

ตัวอย่างค่าที่ไม่ถูกต้อง

ภาษา

หากต้องการทดสอบภาษาต่างๆ ของผู้ใช้ ให้เพิ่มพารามิเตอร์ locale ดังนี้

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

องค์ประกอบของข้อความธรรมดาที่มีคำว่า "Bonjour" พร้อมธงฝรั่งเศส

ตั้งค่าสีพื้นหลัง

โดยค่าเริ่มต้น ระบบจะแสดง Composable ที่มีพื้นหลังโปร่งใส หากต้องการเพิ่มพื้นหลัง ให้เพิ่มพารามิเตอร์ showBackground และ backgroundColor โปรดทราบว่า backgroundColor เป็น ARGB Long ไม่ใช่ค่า Color

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

สี่เหลี่ยมผืนผ้าสีเขียวที่มีคำว่า "Hello
World"

UI ของระบบ

หากต้องการแสดงแถบสถานะและแถบการทำงานภายในตัวอย่าง ให้เพิ่มพารามิเตอร์ showSystemUi

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

หน้าต่างแสดงตัวอย่างกิจกรรมพร้อมแถบสถานะและการดำเนินการ

โหมด UI

พารามิเตอร์ uiMode สามารถใช้ค่าคงที่ Configuration.UI_* ใดก็ได้ และช่วยให้คุณเปลี่ยนลักษณะการทำงานของตัวอย่างได้ตามต้องการ ตัวอย่างเช่น คุณสามารถตั้งค่าตัวอย่างเป็นโหมดกลางคืนเพื่อดูว่าธีมตอบสนองอย่างไร

UI ของตัวอย่าง Compose

LocalInspectionMode

คุณสามารถอ่านจาก LocalInspectionMode CompositionLocal เพื่อดูว่าระบบแสดงผล Composable ในตัวอย่าง (ภายใน คอมโพเนนต์ที่ตรวจสอบได้) หรือไม่ หากระบบแสดงผลการจัดองค์ประกอบในตัวอย่าง LocalInspectionMode.current จะประเมินเป็น true ข้อมูลนี้ช่วยให้คุณปรับแต่งตัวอย่างได้ เช่น คุณสามารถแสดงรูปภาพพื้นที่ที่สำรองไว้ในหน้าต่างตัวอย่างแทนการแสดงข้อมูลจริง

วิธีนี้ยังช่วยให้คุณหลีกเลี่ยงข้อจำกัดได้ด้วย เช่น การแสดงข้อมูลตัวอย่างแทนการเรียกคำขอจากเครือข่าย

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

โต้ตอบกับ @Preview

Android Studio มีฟีเจอร์ที่ช่วยให้คุณโต้ตอบกับตัวอย่างที่กำหนดไว้ได้ การโต้ตอบนี้ช่วยให้คุณเข้าใจลักษณะการทำงานของตัวอย่างในขณะรันไทม์ และช่วยให้คุณไปยังส่วนต่างๆ ของ UI ได้ดีขึ้นด้วยตัวอย่าง

โหมดอินเทอร์แอกทีฟ

โหมดอินเทอร์แอกทีฟช่วยให้คุณโต้ตอบกับตัวอย่างได้ในลักษณะเดียวกับที่คุณโต้ตอบกับอุปกรณ์ที่เรียกใช้โปรแกรม เช่น โทรศัพท์หรือแท็บเล็ต โหมดอินเทอร์แอกทีฟจะแยกอยู่ในสภาพแวดล้อมแซนด์บ็อกซ์ (หมายความว่าแยกจากตัวอย่างอื่นๆ) ซึ่งคุณสามารถคลิกองค์ประกอบและป้อนข้อมูลจากผู้ใช้ในตัวอย่างได้ โหมดนี้เป็นวิธีที่รวดเร็วในการทดสอบสถานะ ท่าทาง และแม้แต่ภาพเคลื่อนไหวต่างๆ ของ Composable

ผู้ใช้คลิกปุ่ม "โต้ตอบ"
ของตัวอย่าง

วิดีโอของผู้ใช้ที่โต้ตอบกับ
ตัวอย่าง

การนำทางโค้ดและโครงร่าง Composable

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

ผู้ใช้เลื่อนเมาส์เหนือตัวอย่าง ทำให้ Studio แสดงโครงร่างของ
คอมโพส

แสดงตัวอย่าง

คุณสามารถเรียกใช้ @Preview ที่เฉพาะเจาะจงในโปรแกรมจำลองหรืออุปกรณ์จริง ระบบจะทำให้ตัวอย่างใช้งานได้ภายในแอปโปรเจ็กต์เดียวกันเป็น Activity ใหม่ ดังนั้นตัวอย่างจึงใช้บริบทและสิทธิ์เดียวกัน คุณไม่จำเป็นต้องเขียนโค้ด Boilerplate ที่ขอสิทธิ์หากได้รับสิทธิ์แล้ว

คลิกไอคอนแสดงตัวอย่าง เรียกใช้การแสดงตัวอย่าง
ไอคอน ข้างคำอธิบายประกอบ @Preview หรือที่ด้านบนของตัวอย่าง แล้ว Android Studio จะทำให้ @Preview นั้นใช้งานได้กับอุปกรณ์ที่เชื่อมต่อหรือโปรแกรมจำลอง

ผู้ใช้คลิกปุ่ม "เรียกใช้ตัวอย่าง" ของตัวอย่าง

วิดีโอของผู้ใช้ที่กำลังติดตั้งใช้งานเวอร์ชันตัวอย่างใน
อุปกรณ์

คัดลอกการแสดงผล @Preview

คุณสามารถคัดลอกตัวอย่างที่แสดงผลทั้งหมดเป็นรูปภาพได้โดยคลิกขวาที่ตัวอย่าง

ผู้ใช้คลิกตัวอย่างเพื่อคัดลอกเป็นรูปภาพ

ตัวอย่างหลายรายการของคำอธิบายประกอบ @Preview เดียวกัน

คุณสามารถแสดง Composable @Preview เดียวกันหลายเวอร์ชันที่มีข้อกำหนดต่างๆ หรือพารามิเตอร์ต่างๆ ที่ส่งไปยัง Composable วิธีนี้จะช่วยให้คุณลดโค้ด Boilerplate ที่คุณจะต้องเขียน

เทมเพลต Multipreview

androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01 ขึ้นไปมีเทมเพลต Multipreview API ได้แก่ @PreviewScreenSizes, @PreviewFontScales, @PreviewLightDark และ @PreviewDynamicColors เพื่อให้คุณดูตัวอย่าง Compose UI ในสถานการณ์ทั่วไปได้ด้วยคำอธิบายประกอบเดียว

การแสดงตัวอย่างแบบอักษรและขนาดหน้าจอต่างๆ โดยใช้เทมเพลต

สร้างคำอธิบายประกอบ Multipreview ที่กำหนดเอง

ด้วย Multipreview คุณสามารถกำหนดคลาสคำอธิบายประกอบที่มีคำอธิบายประกอบ @Preview หลายรายการพร้อมการกำหนดค่าต่างๆ ได้ การเพิ่มคำอธิบายประกอบนี้ลงในฟังก์ชันที่ประกอบกันได้ จะแสดงผลตัวอย่างต่างๆ ทั้งหมดพร้อมกันโดยอัตโนมัติ ตัวอย่างเช่น คุณสามารถใช้คำอธิบายประกอบนี้เพื่อดูตัวอย่างอุปกรณ์ ขนาดแบบอักษร หรือธีมหลายรายการพร้อมกันโดยไม่ต้องทำซ้ำคำจำกัดความเหล่านั้นสำหรับ Composable แต่ละรายการ

เริ่มต้นด้วยการสร้างคลาสคำอธิบายประกอบที่กำหนดเอง

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

คุณสามารถใช้คำอธิบายประกอบที่กำหนดเองนี้สำหรับ Composable ตัวอย่างได้

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

แท็บการออกแบบของ Android Studio แสดง Composable ที่มีแบบอักษรขนาดเล็กและใหญ่

คุณสามารถรวมคำอธิบายประกอบ Multipreview หลายรายการและคำอธิบายประกอบ Preview ปกติเพื่อสร้างชุดตัวอย่างที่สมบูรณ์ยิ่งขึ้น การรวมคำอธิบายประกอบ Multipreview ไม่ได้หมายความว่าระบบจะแสดงชุดค่าผสมต่างๆ ทั้งหมด แต่คำอธิบายประกอบ Multipreview แต่ละรายการจะทำงานแยกกันและแสดงผลเฉพาะตัวแปรของตัวเอง

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

แท็บการออกแบบของ Android Studio แสดง Composable ในการกำหนดค่าทั้งหมด

ลักษณะการผสมและจับคู่ของ Multipreview และ Preview ปกติช่วยให้คุณทดสอบพร็อพเพอร์ตี้ต่างๆ ของโปรเจ็กต์ขนาดใหญ่ได้อย่างครอบคลุมมากขึ้น

@Preview และชุดข้อมูลขนาดใหญ่

บ่อยครั้งที่คุณต้องส่งชุดข้อมูลขนาดใหญ่ไปยังตัวอย่าง Composable หากต้องการทำเช่นนี้ เพียงส่งข้อมูลตัวอย่างไปยังฟังก์ชัน Composable Preview โดย เพิ่มพารามิเตอร์ที่มี @PreviewParameter คำอธิบายประกอบ

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

หากต้องการระบุข้อมูลตัวอย่าง ให้สร้างคลาสที่ใช้ PreviewParameterProvider และแสดงผล ข้อมูลตัวอย่างเป็นลำดับ

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

ซึ่งจะแสดงผลตัวอย่าง 1 รายการต่อองค์ประกอบข้อมูลในลำดับ

ตัวอย่างที่แสดง Elise, Frank และ Julia
Composables

คุณสามารถใช้คลาสผู้ให้บริการเดียวกันสำหรับตัวอย่างหลายรายการ หากจำเป็น ให้จำกัดจำนวนตัวอย่างโดยตั้งค่าพารามิเตอร์ limit

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

โดยค่าเริ่มต้น ระบบจะตั้งชื่อตัวอย่างที่ใช้ @PreviewParameter โดยใช้ดัชนีพารามิเตอร์และชื่อพร็อพเพอร์ตี้ (user 0, user 1, user 2 และอื่นๆ) ซึ่งอาจทำให้แยกความแตกต่างได้ยาก หากต้องการปรับปรุงความชัดเจนของตัวอย่าง คุณสามารถระบุชื่อที่แสดงที่กำหนดเองสำหรับตัวอย่างแต่ละรายการได้โดยการลบล้าง getDisplayName() ใน PreviewParameterProvider ซึ่งจะช่วยแยกความแตกต่างระหว่างข้อมูลที่แตกต่างกันหรือสถานะ UI ตัวอย่างเช่น คุณสามารถติดป้ายกำกับตัวอย่างตามข้อมูลอินพุตได้ดังนี้

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

ตัวอย่างที่มีชื่อที่แสดงที่กำหนดเองซึ่งแสดง Elise - 30, Frank - 31 และ Julia - 40
คอมโพสได้

การสร้างตัวอย่างที่ AI ช่วย

AI Agent ใน Android Studio สามารถสร้างตัวอย่าง Compose สำหรับ Composable ของคุณได้โดยอัตโนมัติ คลิกขวาที่ฟังก์ชันที่ประกอบกันได้ แล้วเลือก AI > Generate Preview for [ชื่อ Composable] เอเจนต์จะวิเคราะห์ Composable เพื่อสร้างเทมเพลต @Preview ที่จำเป็นพร้อมพารามิเตอร์ที่ถูกต้อง ซึ่งจะช่วยให้คุณยืนยันได้อย่างรวดเร็วว่า UI แสดงผลตามที่คาดไว้

สร้างตัวอย่าง Compose โดยใช้ AI

คลาสคำอธิบายประกอบ @Preview

คุณสามารถ 'ctrl หรือ ⌘ + คลิก' คำอธิบายประกอบ @Preview ใน Android Studio ได้ทุกเมื่อเพื่อดูรายการพารามิเตอร์ทั้งหมดที่ปรับได้เมื่อปรับแต่งตัวอย่าง

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

ข้อจำกัดและแนวทางปฏิบัติแนะนำ

Android Studio จะเรียกใช้โค้ดตัวอย่างในพื้นที่ตัวอย่างโดยตรง ไม่จำเป็นต้องเรียกใช้โปรแกรมจำลองหรืออุปกรณ์จริงเนื่องจากใช้ประโยชน์จากส่วนที่พอร์ตของเฟรมเวิร์ก Android ที่เรียกว่า Layoutlib Layoutlib เป็นเฟรมเวิร์ก Android เวอร์ชันที่กำหนดเองซึ่งออกแบบมาให้ทำงานนอกอุปกรณ์ Android เป้าหมายของไลบรารีคือการแสดงตัวอย่างเลย์เอาต์ใน Android Studio ที่ใกล้เคียงกับการแสดงผลบนอุปกรณ์มากที่สุด

ข้อจำกัดของตัวอย่าง

เนื่องจากวิธีที่ระบบแสดงผลตัวอย่างภายใน Android Studio ตัวอย่างจึงมีขนาดเล็กและไม่จำเป็นต้องใช้เฟรมเวิร์ก Android ทั้งหมดในการแสดงผล อย่างไรก็ตาม วิธีนี้มีข้อจำกัดดังต่อไปนี้

  • ไม่มีสิทธิ์เข้าถึงเครือข่าย
  • ไม่มีสิทธิ์เข้าถึงไฟล์
  • API Context บางรายการอาจไม่พร้อมใช้งานอย่างสมบูรณ์

ตัวอย่างและ ViewModels

ตัวอย่างจะถูกจำกัดเมื่อใช้ ViewModel ภายใน a Composable ระบบตัวอย่างไม่สามารถสร้างพารามิเตอร์ทั้งหมดที่ส่งไปยัง ViewModel เช่น ที่เก็บข้อมูล กรณีการใช้งาน ผู้จัดการ หรือสิ่งที่คล้ายกัน นอกจากนี้ หาก ViewModel ของคุณเข้าร่วมในการแทรกทรัพยากร Dependency (เช่น กับ Hilt) ระบบตัวอย่างจะไม่สามารถสร้างกราฟทรัพยากร Dependency ทั้งหมดเพื่อสร้าง ViewModel

เมื่อคุณพยายามดูตัวอย่าง Composable ที่มี ViewModel Android Studio จะแสดงข้อผิดพลาดเมื่อแสดงผล Composable ที่เฉพาะเจาะจง

แผงปัญหาของ Android Studio ที่มีข้อความ &quot;สร้างอินสแตนซ์ของ `ViewModel` ไม่สำเร็จ&quot;

หากต้องการดูตัวอย่าง Composable ที่ใช้ ViewModel คุณควรสร้าง Composable อีกรายการหนึ่งที่มีพารามิเตอร์จาก ViewModel ที่ส่งเป็นอาร์กิวเมนต์ของ Composable วิธีนี้จะช่วยให้คุณไม่จำเป็นต้องดูตัวอย่าง Composable ที่ใช้ ViewModel

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

แหล่งข้อมูลเพิ่มเติม

หากต้องการอ่านเพิ่มเติมเกี่ยวกับวิธีที่ Android Studio ส่งเสริมความสะดวกในการใช้งาน @Preview และเรียนรู้เคล็ดลับเพิ่มเติมเกี่ยวกับเครื่องมือ โปรดดูบล็อก Compose Tooling