ข่าวสารผลิตภัณฑ์

มีอะไรใหม่ใน Jetpack Compose เวอร์ชันสิงหาคม 2026

ใช้เวลาอ่าน 5 นาที
ดูโปรไฟล์ของ Nick Butcher
Nick Butcher ผู้จัดการผลิตภัณฑ์

วันนี้ Jetpack Compose เวอร์ชันสิงหาคม 2026 พร้อมให้ใช้งานอย่างเสถียรแล้ว เวอร์ชันนี้มาพร้อมกับเวอร์ชัน 1.12 ในโมดูลหลักของ Compose (ดูการแมป BOMทั้งหมด) โดยมี API ภาพที่สมบูรณ์ เช่น Mesh Gradients และการรองรับ Wide Color Gamut (WCG), ฟีเจอร์เลย์เอาต์โครงสร้าง เช่น พื้นที่ที่มีชื่อในGrid การผสานรวมกับ Credential Manager ของ Android อย่างราบรื่น รวมถึงการปรับปรุงการทดสอบและประสิทธิภาพอย่างมีนัยสำคัญ

หากต้องการอัปเดตโปรเจ็กต์เป็นเวอร์ชันปัจจุบัน ให้อัปเกรดเวอร์ชัน Compose BOM เป็น 2026.08.00

implementation(platform("androidx.compose:compose-bom:2026.08.00"))

การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ

  • AGP และ Compile SDK: Compose 1.12 อัปเดต compileSdk เป็น API 37 ซึ่งต้องใช้ AGP 9.1.2 ขึ้นไป โปรดทราบว่า Compose จะกำหนดเป้าหมายเป็น compileSdk เวอร์ชันล่าสุดเสมอ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงนี้ ที่นี่.
  • Modifier.onFirstVisible() เลิกใช้งานแล้ว: ย้ายข้อมูลไปยัง Modifier.onVisibilityChanged() ซึ่งมีการติดตามเกณฑ์การมองเห็นที่แม่นยำยิ่งขึ้น

กราฟิก

Mesh Gradients

Compose 1.12 ขอแนะนำ MeshGradientPainter เพื่อช่วยคุณสร้างการไล่ระดับสีแบบหลายจุดและเป็นธรรมชาติ

meshGradient.gif
val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)

ดูข้อมูลเพิ่มเติมและตัวอย่างได้ใน เอกสารประกอบ

การรองรับ Wide Color Gamut และ HDR

จอแสดงผลสมัยใหม่มีความเที่ยงตรงของสีที่มากขึ้นและช่วงไดนามิกที่สูงขึ้น ใน Compose 1.12 เราได้เปิดใช้การรองรับไปป์ไลน์แบบเต็มสำหรับ Wide Color Gamut (P3) และ การแสดงผล HDR ในกราฟิก สี และ Shader ของ Compose ระบบจะเก็บสีที่กำหนดไว้ในพื้นที่สีที่ไม่ใช่ sRGB (เช่น Display P3) ไว้จนถึงการแสดงผลของแพลตฟอร์มโดยไม่มีการหนีบสี สีจะกลับไปใช้ sRGB อย่างปลอดภัยหากใช้พื้นที่สีที่ไม่รองรับ (เช่น CieXyz, CieLab หรือ Oklab) อาศัยพื้นที่สีใน Android เวอร์ชันที่ไม่รองรับ (เช่น Bt2020Hlg ใน Android 13 และต่ำกว่า) หรือหากแอปทำงานบน Android 9 (API 28) และต่ำกว่า

การเปลี่ยนแปลงที่สำคัญอื่นๆ

  • LayerOutsets ได้ถูกเพิ่มไปยัง GraphicsLayer & Modifier.graphicsLayer ซึ่งคุณสามารถใช้เพื่อเพิ่มขอบเขตภาพของเลเยอร์ให้เกินขนาดที่วัดได้ ใช้ LayerOutsets เพื่อหลีกเลี่ยงลักษณะการทำงาน clipToBounds โดยนัยเมื่อเลเยอร์ได้รับการเลื่อนระดับเป็นบัฟเฟอร์นอกหน้าจอ

รูปแบบ

ในงาน Google I/O เราได้แชร์วิสัยทัศน์เบื้องต้นเกี่ยวกับ Compose Styles API ซึ่งเป็นวิธีที่รวมเป็นหนึ่งเดียวและมีประสิทธิภาพในการจัดรูปแบบคอมโพเนนต์ ตั้งแต่นั้นมา เราได้สร้างสถาปัตยกรรมพื้นฐานต่อไปเพื่อให้มั่นใจในความปลอดภัยในการกำหนดประเภทที่เข้มงวดและความถูกต้องที่คาดการณ์ได้ รวมถึงรองรับการสร้างระบบการออกแบบที่กำหนดเอง

API จะยังคงอยู่ในสถานะทดลองใช้และคุณอาจพบกับการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ เพื่อให้มั่นใจว่าเราจะสร้างเลเยอร์พื้นฐานนี้ได้อย่างถูกต้อง

การเพิ่มประสิทธิภาพรันไทม์

การโอเวอร์โหลด SideEffectที่ใช้คีย์

SideEffect ตอนนี้รองรับอาร์กิวเมนต์คีย์ ซึ่งช่วยให้คุณทริกเกอร์ Side Effect แบบครั้งเดียวได้ทุกเมื่อที่คีย์ที่เฉพาะเจาะจงมีการเปลี่ยนแปลง ซึ่งอาจส่งผลให้มีประสิทธิภาพดีขึ้นเมื่อเทียบกับการใช้ LaunchedEffect หรือ DisposableEffect ในกรณีที่คุณไม่ต้องการโครูทีนหรือบล็อกการทิ้ง SideEffect เร็วกว่า LaunchedEffect สูงสุด 90% และเร็วกว่า DisposableEffect ประมาณ 20% โปรดทราบว่า SideEffect จะเรียกใช้เอฟเฟกต์ก่อน DisposableEffect และ LaunchedEffect ดังนั้นโปรดใช้ความระมัดระวังหากย้ายเอฟเฟกต์ที่มีอยู่ไปยัง API นี้ โดยเฉพาะอย่างยิ่งสำหรับ LaunchedEffects ที่ต้องอาศัยการส่งเพื่อเริ่มต้นหลังจากเฟรมปัจจุบันเสร็จสมบูรณ์

@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}

ภาพเคลื่อนไหว

การเปลี่ยนภาพแบบ 2 ขั้นตอนแบบโต้ตอบ

  • คอมโพสได้ใหม่DeferredAnimatedContent และ DeferredAnimatedVisibility ช่วยให้สร้างการเปลี่ยนภาพแบบ 2 ขั้นตอนที่น่าสนใจได้ เช่น สำหรับการติดตามท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้
  • การควบคุมภาพเคลื่อนไหวด้วยตนเอง: ในระหว่างระยะที่เลื่อนออกไปของการเปลี่ยนภาพ ตอนนี้คุณสามารถจัดการพร็อพเพอร์ตี้ภาพเคลื่อนไหว (เช่น การปรับขนาดหรือออฟเซ็ต) ด้วยตนเองแบบเรียลไทม์ได้ (เช่น การติดตามท่าทางสัมผัสการปัด)
  • การส่งต่อที่ราบรื่น: เมื่อระยะที่เลื่อนออกไปสิ้นสุดลง เครื่องมือการเปลี่ยนผ่านจะเข้าควบคุมและทำการส่งต่อที่ราบรื่น รวมถึงการโอนอัตราความเร็วไปยังการเปลี่ยนผ่านอัตโนมัติ
  • การรองรับองค์ประกอบที่แชร์: แฟล็ก permitTransformDuringDeferredTransition ใหม่ใน SharedContentConfig จะควบคุมว่าองค์ประกอบที่แชร์จะเปลี่ยนรูปภาพไปพร้อมกับคอนเทนเนอร์ระดับบนหรือไม่ในระหว่างระยะการเปลี่ยนภาพที่เลื่อนออกไป
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen ->
    ScreenContent(screen)
}

ด้านล่างนี้คือการสาธิต 2 รายการของกรณีการใช้งานที่ระบบจะส่งต่อภาพเคลื่อนไหวที่ขับเคลื่อนด้วยท่าทางสัมผัสไปยังภาพเคลื่อนไหวที่ทริกเกอร์

colorCards.gif

ข้อความ อินพุต และการผสานรวมแพลตฟอร์ม

การจัดรูปแบบข้อความที่แก้ไขได้

API ใหม่มีการจัดรูปแบบ Rich Text สำหรับข้อความที่แก้ไขได้ใน BasicTextField. ตอนนี้คุณสามารถใช้และจัดการการจัดรูปแบบอักขระและย่อหน้าแบบอินไลน์โดยใช้ SpanStyle และ ParagraphStyle ผ่านเมธอด addStyle() ใหม่ภายในขอบเขต TextFieldBuffer (เช่น ภายใน textFieldState.edit { ... } หรือ InputTransformation) ได้แล้ว นอกจากนี้ TextFieldBuffer ยังมี API getSpanStyles() และ getParagraphStyles() ที่แสดงออบเจ็กต์ TrackedRange ซึ่งช่วยให้คุณอ่าน อัปเดต หรือนำรูปแบบที่ใช้ไปออกได้ TextFieldState จะแสดงพร็อพเพอร์ตี้ textStyles แบบอ่านอย่างเดียวสำหรับการค้นหาสไตล์ที่ใช้งานอยู่ทั่วทั้งช่วง ในขณะที่ TextFieldBuffer มี originalTextStyles สำหรับตรวจสอบสถานะการจัดรูปแบบก่อนการแก้ไข เพื่อเสริมการสร้างการจัดรูปแบบ ระบบจะเก็บการจัดรูปแบบข้อความและคำอธิบายประกอบที่กำหนดเองไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า

val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles

การเลือกข้อความ

API SelectionState ใหม่ช่วยให้ควบคุมและสังเกตการเลือกข้อความภายใน SelectionContainer ได้โดยโปรแกรม การโฮสต์ออบเจ็กต์ SelectionState ผ่าน rememberSelectionState() และส่งไปยัง SelectionContainer จะแสดง selectedTexts เป็นรายการแบบโต้ตอบของ AnnotatedStrings และมีเมธอดต่างๆ เช่น selectAll(), clear(), select(TextRange) และ extendSelectionByWord()

นอกจากนี้ ให้ใช้ getSelectableTexts() เพื่อดึงข้อมูลรายการข้อความทั้งหมดที่เลือกได้ตามลำดับเลย์เอาต์ และเลือกข้อความในคอมโพสได้ใน SelectionContainer โดยใช้ช่วงส่วนกลาง

@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}

การผสานรวม Credential Manager

ตอนนี้ช่องข้อความของ Compose ผสานรวมกับ Credential Manager (API 34 ขึ้นไป) ของ Android โดยกำเนิดผ่านเฟรมเวิร์กการป้อนข้อความอัตโนมัติ (ระบบจะจัดการ API 34 ลงไปโดย androidx.credentials library) การแนบพร็อพเพอร์ตี้ความหมาย credentialRequest ใหม่กับ CredentialRequestData จะช่วยให้การป้อนข้อความแจ้งให้ผู้ใช้ป้อนพาสคีย์ ข้อมูลเข้าสู่ระบบที่บันทึกไว้ หรือคำขอลงชื่อเข้าใช้ได้โดยตรงภายในโฟลว์การป้อนข้อมูลของผู้ใช้

@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}

การเปลี่ยนแปลงที่สำคัญอื่นๆ

  • การรองรับการตั้งค่ารูปแบบตัวอักษรในแบบอักษรที่ดาวน์โหลดได้
  • เปิดใช้การเลื่อนอัตโนมัติเมื่อลากการเลือกข้อความออกนอกวิวพอร์ตในSelectionContainer
  • เพิ่มการรองรับเสียงการโต้ตอบอัตโนมัติ (การคลิกและการนำทางโฟกัส) ลงในคอมโพเนนต์ Compose โดยมีคอมโพสได้ SoundEffectOnInteraction ใหม่เพื่อให้เลือกไม่ใช้ได้ โปรดทราบว่าการเปลี่ยนแปลงนี้จะส่งผลให้ต้องเรียกใช้ Listener การคลิกความหมายจากเทรดหลัก ซึ่งอาจส่งผลต่อกรณีทดสอบจำนวนเล็กน้อย
  • KeyboardType ตอนนี้มี DateTimeDateTime, และ SignedDecimal แล้ว
  • BasicSecureTextField ตอนนี้ใช้ TextObfuscationMode.System เป็นค่าเริ่มต้น ในขณะที่ RevealLastTyped จะทำหน้าที่เป็นการลบล้างแบบสมบูรณ์

การปรับปรุงเลย์เอาต์

พื้นที่ที่มีชื่อในเลย์เอาต์ Grid

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

@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}

ดูข้อมูลเพิ่มเติมได้ในเอกสารประกอบ

ประสิทธิภาพ

เช่นเดียวกับทุกเวอร์ชัน เรายังคงลงทุนในประสิทธิภาพของ Compose เพื่อให้มั่นใจว่าเฟรมเวิร์กจะช่วยคุณสร้างแอปที่สวยงามและมีประสิทธิภาพ ในเวอร์ชันนี้ เรามุ่งเน้นที่การปรับปรุงประสิทธิภาพการเริ่มต้นแอป และตอนนี้เราเห็นเวลาจนกว่าจะแสดงผลครั้งแรก (เวลาที่แอปใช้ในการสร้างเฟรมแรก) เทียบได้กับ Views ใน การทดสอบประสิทธิภาพ

timetoinitialdisplay@2x _v2.png

การอัปเกรดการทดสอบและเครื่องมือ

การซิงค์การทดสอบ

Compose 1.12 ขอแนะนำ API การทดสอบใหม่ที่ออกแบบมาเพื่อลดเวลาการดำเนินการทดสอบและขจัดความไม่แน่นอนระหว่างการสุ่มตัวอย่างสถานะ

  • hasPendingWork: ตรวจสอบแบบพาสซีฟว่า UI มีงานที่รอดำเนินการอยู่หรือไม่โดยไม่เลื่อนเวลา ซึ่งเหมาะสำหรับลูปภาพเคลื่อนไหวด้วยตนเอง
  • runWithoutImplicitWait: ปิดใช้การซิงค์โดยนัยชั่วคราวเมื่อก้าวผ่านเฟรมเวลาด้วยตนเอง (เช่น การทดสอบภาพเคลื่อนไหว)
@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}

การเปลี่ยนแปลงที่สำคัญอื่นๆ

  • ตอนนี้ API captureToImage ช่วยให้คุณจับภาพป๊อปอัปหรือกล่องโต้ตอบพร้อมกับ Anchor ในบิตแมปเดียวได้
  • เพิ่ม onRootWithViewInteraction เพื่อกำหนดขอบเขตการค้นหาความหมายของ Compose ให้กับ Android View ที่เฉพาะเจาะจง ซึ่งจะช่วยลดความซับซ้อนในการทดสอบ UI แบบไฮบริด เช่น RecyclerViews โดยไม่ต้องใช้แท็กทดสอบที่ไม่ซ้ำกันในโค้ดโปรดักชัน
  • @PreviewWrapper ตอนนี้คุณสามารถใช้คำอธิบายประกอบกับคลาส @MultiPreview ที่กำหนดเองได้ ซึ่งจะช่วยให้ตั้งค่าการแสดงตัวอย่างที่ใช้ซ้ำได้ (เช่น ธีมที่กำหนดเอง) ในคอมโพเนนต์หลายรายการ

ขอให้สนุกกับการเขียนโค้ดด้วย Compose

Compose 1.12 ช่วยให้การพัฒนาแอปง่ายขึ้นและแสดงออกได้มากขึ้นกว่าที่เคยด้วย Mesh Gradients, การรองรับ Wide Color Gamut, แบบอักษรตัวแปรที่ดาวน์โหลดได้, การผสานรวม Credential Manager และเครื่องมือทดสอบที่เร็วขึ้น เราให้ความสำคัญกับความคิดเห็นของคุณเสมอ ดังนั้นโปรดแชร์ความคิดเห็นเกี่ยวกับการเปลี่ยนแปลงเหล่านี้หรือสิ่งที่คุณต้องการเห็นต่อไปใน เครื่องมือติดตามปัญหา ขอให้สนุกกับการเขียนโค้ดด้วย Compose

เขียนโดย:
อ่านต่อ