แม้ว่าการย้ายข้อมูลจากมุมมองไปยังการเขียนจะเกี่ยวข้องกับ UI เพียงอย่างเดียว แต่ก็มี สิ่งที่ต้องคำนึงถึงเพื่อให้การย้ายข้อมูลเพิ่มขึ้นอย่างปลอดภัย ช่วงเวลานี้ มีข้อควรพิจารณาขณะย้ายข้อมูล แอปที่อิงตามการดูไปยัง Compose
การย้ายข้อมูลธีมของแอป
ดีไซน์ Material เป็นระบบการออกแบบที่แนะนำสำหรับการกำหนดธีมของแอป Android
สำหรับแอปที่อิงตามการดู จะมี Material ให้ดาวน์โหลด 3 เวอร์ชันดังนี้
- ดีไซน์ Material 1 ที่ใช้
ไลบรารี AppCompat (นั่นคือ
Theme.AppCompat.*
) - ดีไซน์ Material 2 ที่ใช้องค์ประกอบ
MDC-Android
ไลบรารี (เช่น
Theme.MaterialComponents.*
) - ดีไซน์ Material 3 ที่ใช้องค์ประกอบ
MDC-Android
ไลบรารี (เช่น
Theme.Material3.*
)
สำหรับแอป Compose มี Material ให้ใช้งาน 2 เวอร์ชัน ดังนี้
- ดีไซน์ Material 2 โดยใช้
ไลบรารีเขียนเนื้อหา
(เช่น
androidx.compose.material.MaterialTheme
) - ดีไซน์ Material 3 ที่ใช้องค์ประกอบ
ไลบรารีเขียน Material 3
(เช่น
androidx.compose.material3.MaterialTheme
)
เราขอแนะนำให้ใช้เวอร์ชันล่าสุด (เนื้อหา 3) หากระบบการออกแบบของแอป อยู่ในสถานะที่จะทำเช่นนั้นได้ เรามีคําแนะนําในการย้ายข้อมูลสําหรับข้อมูลพร็อพเพอร์ตี้ทั้ง 2 รายการ และเขียน:
- วัสดุ 1 ถึงวัสดุ 2 ในการแสดงผล
- Material 2 ถึง Material 3 ในยอดดู
- Material 2 ถึง Material 3 ในการเขียน
เมื่อสร้างหน้าจอใหม่ใน Compose ไม่ว่าจะเป็น Material เวอร์ชันใดก็ตาม
การออกแบบที่คุณใช้อยู่ อย่าลืมใช้ MaterialTheme
ก่อน
Composable ที่แสดง UI จากไลบรารี Material ของ Compose วัสดุ
คอมโพเนนต์ (Button
, Text
ฯลฯ) ขึ้นอยู่กับ MaterialTheme
ที่ใช้อยู่
และพฤติกรรมของผู้อ่านจะไม่มีทางกำหนดได้หากไม่มีความสามารถนี้
ทั้งหมด
ตัวอย่าง Jetpack Compose
ใช้ธีม Compose ที่กําหนดเองซึ่งสร้างจาก MaterialTheme
โปรดดูข้อมูลเพิ่มเติมที่ออกแบบระบบใน Compose และการย้ายข้อมูลธีม XML ไปยัง Compose
การไปยังรายการต่างๆ
หากคุณใช้คอมโพเนนต์การนำทางในแอป โปรดดู การไปยังส่วนต่างๆ ด้วยการเขียน - ความสามารถในการทำงานร่วมกัน และ ย้ายข้อมูลการนำทางใน Jetpack ไปยังฟีเจอร์ช่วยเขียนในการไปยังส่วนต่างๆ เพื่อดูข้อมูลเพิ่มเติม
ทดสอบ UI การเขียน/มุมมองแบบผสมของคุณ
หลังจากย้ายส่วนต่างๆ ของแอปไปยัง Compose แล้ว การทดสอบมีความสำคัญอย่างยิ่งเพื่อให้มั่นใจว่า คุณยังไม่ได้หักอะไรเลย
เมื่อกิจกรรมหรือส่วนย่อยใช้การเขียน คุณต้องใช้
createAndroidComposeRule
แทนการใช้ ActivityScenarioRule
createAndroidComposeRule
ผสานรวม
ActivityScenarioRule
ด้วย ComposeTestRule
ที่ให้คุณทดสอบ Compose และ
ดูโค้ดในเวลาเดียวกัน
class MyActivityTest { @Rule @JvmField val composeTestRule = createAndroidComposeRule<MyActivity>() @Test fun testGreeting() { val greeting = InstrumentationRegistry.getInstrumentation() .targetContext.resources.getString(R.string.greeting) composeTestRule.onNodeWithText(greeting).assertIsDisplayed() } }
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทดสอบได้ที่การทดสอบเลย์เอาต์ของ Compose สำหรับ ความสามารถในการทำงานร่วมกันกับเฟรมเวิร์กการทดสอบ UI โปรดดู ความสามารถในการทำงานร่วมกับ Espresso และ ความสามารถในการทำงานร่วมกับ UiAutomator
การผสานรวม Compose กับสถาปัตยกรรมแอปที่มีอยู่
สถาปัตยกรรม Unidirectional Data Flow (UDF) จะทำงานร่วมกับ Compose ได้อย่างราบรื่น หากแอปใช้ประเภท รูปแบบสถาปัตยกรรมแบบเดิม อย่างเช่น ตัวนำเสนอมุมมองโมเดล (MVP) เราขอแนะนำให้คุณ ย้ายข้อมูลส่วนนั้นของ UI ไปยัง UDF ก่อนหรือในขณะที่ใช้ Compose
การใช้ ViewModel
ในการเขียน
ถ้าคุณใช้คอมโพเนนต์สถาปัตยกรรม
ไลบรารี ViewModel
คุณจะเข้าถึง
ViewModel
จาก Composable โดย
การเรียกฟังก์ชัน
viewModel()
ตามที่อธิบายไว้ในการเขียนและไลบรารีอื่นๆ
เมื่อนำการเขียนมาใช้ โปรดระมัดระวังการใช้ ViewModel
ประเภทเดียวกันใน
Composable ที่ต่างกันเนื่องจากองค์ประกอบ ViewModel
จะเป็นไปตามขอบเขตวงจรการดู
จะเป็นกิจกรรมโฮสต์ ส่วนย่อย หรือกราฟการนำทาง หาก
ใช้ไลบรารีการนำทาง
ตัวอย่างเช่น หาก Composable โฮสต์อยู่ในกิจกรรม viewModel()
จะเป็น
แสดงผลอินสแตนซ์เดียวกันที่ถูกล้างไปเมื่อกิจกรรมเสร็จสิ้นเท่านั้น
ในตัวอย่างต่อไปนี้ ผู้ใช้เดียวกัน ("user1") ได้รับการทักทายสองครั้งเนื่องจาก
จะมีการนำอินสแตนซ์ GreetingViewModel
เดียวกันมาใช้ซ้ำใน Composable ทั้งหมดภายใต้
กิจกรรมของโฮสต์ อินสแตนซ์ ViewModel
รายการแรกที่สร้างจะมีการใช้ซ้ำในอินสแตนซ์อื่นๆ
Composable
class GreetingActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MaterialTheme { Column { GreetingScreen("user1") GreetingScreen("user2") } } } } } @Composable fun GreetingScreen( userId: String, viewModel: GreetingViewModel = viewModel( factory = GreetingViewModelFactory(userId) ) ) { val messageUser by viewModel.message.observeAsState("") Text(messageUser) } class GreetingViewModel(private val userId: String) : ViewModel() { private val _message = MutableLiveData("Hi $userId") val message: LiveData<String> = _message } class GreetingViewModelFactory(private val userId: String) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { return GreetingViewModel(userId) as T } }
เนื่องจากกราฟการนำทางยังกำหนดขอบเขตขององค์ประกอบ ViewModel
ด้วย Composable ที่เป็น
ปลายทางในกราฟการนำทางมีอินสแตนซ์ของ ViewModel
ต่างกัน
ในกรณีนี้ ViewModel
จะกําหนดขอบเขตไว้ที่วงจรของปลายทาง และ
ระบบจะล้างเมื่อปลายทางถูกนำออกจาก Backstack ใน
ตัวอย่างต่อไปนี้ เมื่อผู้ใช้ไปที่หน้าจอโปรไฟล์
สร้างอินสแตนซ์ของ GreetingViewModel
แล้ว
@Composable fun MyApp() { NavHost(rememberNavController(), startDestination = "profile/{userId}") { /* ... */ composable("profile/{userId}") { backStackEntry -> GreetingScreen(backStackEntry.arguments?.getString("userId") ?: "") } } }
แหล่งข้อมูลความจริงของรัฐ
เมื่อคุณใช้งานการเขียนในส่วนหนึ่งของ UI อาจเป็นไปได้ว่าการเขียนและ
ต้องแชร์ข้อมูลด้วยโค้ดของระบบ เมื่อเป็นไปได้ เราขอแนะนำให้คุณ
สรุปสถานะที่แชร์ในชั้นเรียนอื่นที่เป็นไปตามแนวทางปฏิบัติแนะนำของ UDF
ที่ใช้โดยทั้ง 2 แพลตฟอร์ม ตัวอย่างเช่น ใน ViewModel
ที่แสดงสตรีมของ
ข้อมูลที่แชร์เพื่อปล่อยการอัปเดต
อย่างไรก็ตาม นั่นเป็นไปไม่ได้เสมอไปหากข้อมูลที่จะแชร์นั้นเปลี่ยนแปลงได้หรือ เชื่อมโยงกับองค์ประกอบ UI อย่างแน่นหนา ในกรณีนั้น ระบบหนึ่งต้องเป็นแหล่งที่มาของ และระบบนั้นจำเป็นต้องแชร์ข้อมูลอัปเดตไปยังอีกระบบหนึ่งด้วย เพื่อ หลักการทั่วไป แหล่งข้อมูลที่ถูกต้องควรเป็นเจ้าขององค์ประกอบใดก็ตาม จะอยู่ใกล้กับรูทของลำดับชั้น UI
เขียนเป็นแหล่งข้อมูลที่ถูกต้อง
ใช้เมนู
SideEffect
Composable เพื่อเผยแพร่สถานะ Compose ไปยังโค้ดที่ไม่ใช่ Compose ในกรณีนี้ ค่า
จะเก็บไว้ใน Composable ซึ่งจะส่งการอัปเดตสถานะ
ตัวอย่างเช่น ไลบรารีข้อมูลวิเคราะห์อาจช่วยให้คุณแบ่งกลุ่มผู้ใช้ได้
การป้อนข้อมูลด้วยการแนบข้อมูลเมตาที่กำหนดเอง (พร็อพเพอร์ตี้ผู้ใช้ในตัวอย่างนี้)
กับเหตุการณ์ Analytics อื่นๆ ที่ตามมาทั้งหมด ในการสื่อสารประเภทผู้ใช้ของ
ผู้ใช้ปัจจุบันในไลบรารีข้อมูลวิเคราะห์ของคุณ ใช้ SideEffect
เพื่ออัปเดตค่า
@Composable fun rememberFirebaseAnalytics(user: User): FirebaseAnalytics { val analytics: FirebaseAnalytics = remember { FirebaseAnalytics() } // On every successful composition, update FirebaseAnalytics with // the userType from the current User, ensuring that future analytics // events have this metadata attached SideEffect { analytics.setUserProperty("userType", user.userType) } return analytics }
ดูข้อมูลเพิ่มเติมได้ที่ผลข้างเคียงใน Compose
ดูระบบเป็นแหล่งข้อมูลที่ถูกต้อง
หากระบบ View เป็นเจ้าของรัฐและแชร์รัฐนั้นกับ Compose เราขอแนะนำให้ทำดังนี้
คุณรวมสถานะไว้ในออบเจ็กต์ mutableStateOf
เพื่อให้เป็นชุดข้อความปลอดภัยสำหรับ
เขียน หากคุณใช้วิธีนี้ ฟังก์ชันที่ประกอบกันได้จะเรียบง่ายขึ้นเนื่องจาก
จะไม่มีแหล่งข้อมูลที่ถูกต้องอีกต่อไป แต่ระบบ View จำเป็นต้องอัปเดต
สถานะที่เปลี่ยนแปลงได้และมุมมองที่ใช้สถานะนั้น
ในตัวอย่างต่อไปนี้ CustomViewGroup
มี TextView
และ
ComposeView
ที่มี TextField
Composable ด้านใน TextView
จำเป็นต้องแสดง
เนื้อหาของสิ่งที่ผู้ใช้พิมพ์ใน TextField
class CustomViewGroup @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 ) : LinearLayout(context, attrs, defStyle) { // Source of truth in the View system as mutableStateOf // to make it thread-safe for Compose private var text by mutableStateOf("") private val textView: TextView init { orientation = VERTICAL textView = TextView(context) val composeView = ComposeView(context).apply { setContent { MaterialTheme { TextField(value = text, onValueChange = { updateState(it) }) } } } addView(textView) addView(composeView) } // Update both the source of truth and the TextView private fun updateState(newValue: String) { text = newValue textView.text = newValue } }
กำลังย้ายข้อมูล UI ที่ใช้ร่วมกัน
หากคุณค่อยๆ ย้ายข้อมูลไปยัง Compose คุณอาจต้องใช้ UI ที่ใช้ร่วมกัน
ทั้งในระบบ "เขียน" และ "ดู" เช่น หากแอปของคุณมี
คอมโพเนนต์ CallToActionButton
ที่กำหนดเอง คุณอาจต้องใช้งานทั้งใน Compose
และหน้าจอที่อิงตามการดู
ใน Compose องค์ประกอบ UI ที่แชร์จะกลายเป็น Composable ที่สามารถนำมาใช้ซ้ำใน
โดยไม่คำนึงถึงองค์ประกอบที่ได้รับการจัดรูปแบบโดยใช้ XML หรือเป็นมุมมองที่กำหนดเอง สำหรับ
เช่น คุณจะต้องสร้าง CallToActionButton
Composable สำหรับการเรียกที่กำหนดเองเพื่อ
การทำงาน Button
หากต้องการใช้ Composable ในหน้าจอที่อิงตามการดู ให้สร้าง Wrapper มุมมองที่กำหนดเอง
เริ่มจาก AbstractComposeView
ใน Composable Content
ที่ถูกลบล้าง
วาง Composable ที่คุณสร้างขึ้นโดยรวมในธีม Compose ดังที่แสดงใน
ตัวอย่างด้านล่าง
@Composable fun CallToActionButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, ) { Button( colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.secondary ), onClick = onClick, modifier = modifier, ) { Text(text) } } class CallToActionViewButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 ) : AbstractComposeView(context, attrs, defStyle) { var text by mutableStateOf("") var onClick by mutableStateOf({}) @Composable override fun Content() { YourAppTheme { CallToActionButton(text, onClick) } } }
โปรดสังเกตว่าพารามิเตอร์ Composable จะกลายเป็นตัวแปรที่เปลี่ยนแปลงได้ภายในที่กำหนดเอง
ซึ่งทำให้มุมมอง CallToActionViewButton
ที่กำหนดเองเป็นแบบเป่าลมและใช้งานได้
มุมมองดั้งเดิม ดูตัวอย่างของส่วนนี้ด้วย View Binding
ด้านล่าง
class ViewBindingActivity : ComponentActivity() { private lateinit var binding: ActivityExampleBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityExampleBinding.inflate(layoutInflater) setContentView(binding.root) binding.callToAction.apply { text = getString(R.string.greeting) onClick = { /* Do something */ } } } }
หากคอมโพเนนต์ที่กำหนดเองมีสถานะที่เปลี่ยนแปลงได้ โปรดดูแหล่งที่มาของสถานะของ ความจริง
ให้ความสำคัญกับสถานะการแยกออกจากงานนำเสนอ
เดิมที View
จะเป็นแบบเก็บสถานะ View
จะจัดการช่องที่
อธิบายอะไรที่จะแสดง นอกเหนือจากวิธีแสดง เมื่อคุณ
แปลง View
เป็น Compose, มองหาเพื่อแยกข้อมูลที่แสดงผล
ทำให้เกิดการถ่ายโอนข้อมูลที่เป็นทิศทางเดียวกัน ตามที่อธิบายไว้เพิ่มเติมในการล้างสถานะ
ตัวอย่างเช่น View
มีพร็อพเพอร์ตี้ visibility
ที่อธิบายในกรณีที่
มองเห็นได้ มองไม่เห็น หรือหายไป นี่เป็นพร็อพเพอร์ตี้ที่มีอยู่ของ View
ขณะที่
ส่วนรหัสอื่นๆ อาจเปลี่ยนการแสดง View
แต่เฉพาะ View
ทราบดีอยู่แล้วว่าระดับการเข้าถึงในปัจจุบันเป็นอย่างไร ตรรกะในการตรวจสอบว่า
View
อาจมีความเสี่ยงที่จะเกิดข้อผิดพลาด และมักเชื่อมโยงกับ View
โดยตรง
ในทางตรงกันข้าม Compose ทำให้การแสดง Composable ที่แตกต่างกันโดยสิ้นเชิงเป็นเรื่องง่าย โดยใช้ตรรกะตามเงื่อนไขใน Kotlin
@Composable fun MyComposable(showCautionIcon: Boolean) { if (showCautionIcon) { CautionIcon(/* ... */) } }
ตามการออกแบบแล้ว CautionIcon
ไม่จำเป็นต้องรู้หรือสนใจว่าทำไมจึงแสดงโฆษณานี้
และไม่มีแนวคิดของ visibility
เพราะอาจอยู่ในองค์ประกอบ หรือ
ใช้ไม่ได้
การแยกการจัดการสถานะและตรรกะการนำเสนอออกจากกันอย่างชัดเจน ทำให้คุณสามารถ เปลี่ยนวิธีแสดงเนื้อหาเป็นการแปลงสถานะเป็น UI ได้อย่างอิสระ การอยู่ สามารถยกสถานะเมื่อต้องการ ทำให้ Composable นำมาใช้ซ้ำได้มากขึ้นเนื่องจาก การเป็นเจ้าของในแต่ละรัฐนั้นยืดหยุ่นกว่า
โปรโมตส่วนประกอบที่ห่อหุ้มและนำมาใช้ใหม่ได้
องค์ประกอบ View
มักทราบตำแหน่งที่ตั้งของสิ่งนั้น เช่น ภายใน Activity
Dialog
, Fragment
หรือที่อื่นภายในลําดับชั้น View
อื่น เพราะ
ไฟล์มักพองขึ้นจากไฟล์เลย์เอาต์แบบคงที่ ซึ่งเป็นโครงสร้างโดยรวมของ
View
มีแนวโน้มที่จะตายตัวมาก ซึ่งทำให้เกิดการเชื่อมต่อที่แน่นแฟ้นขึ้น
View
จะเปลี่ยนแปลงหรือนำมาใช้ซ้ำได้ยากขึ้น
ตัวอย่างเช่น View
ที่กำหนดเองอาจคิดว่ามีมุมมองย่อยของ
พิมพ์ด้วยรหัสที่กำหนด และเปลี่ยนคุณสมบัติโดยตรงตามรหัสบางรายการ
การดำเนินการ การดำเนินการนี้จะจับคู่องค์ประกอบ View
เหล่านั้นเข้าด้วยกันอย่างเหนียวแน่น: View
ที่กำหนดเอง
อาจขัดข้องหรือเสียหายหากไม่พบเด็ก และเด็กมีแนวโน้มที่จะหาไม่เจอ
ก็ใช้ซ้ำได้โดยไม่ต้องใช้ View
ระดับบนสุดที่กำหนดเอง
ซึ่งปัญหาน้อยกว่าใน Compose กับ Composable ที่นำมาใช้ใหม่ได้ ผู้ปกครองสามารถ ระบุสถานะและ Callback ได้โดยง่าย เพื่อให้คุณเขียน Composable ที่นำมาใช้ใหม่ได้ โดยไม่ต้องทราบที่แน่ชัดว่าจะนำไปใช้งานที่ใด
@Composable fun AScreen() { var isEnabled by rememberSaveable { mutableStateOf(false) } Column { ImageWithEnabledOverlay(isEnabled) ControlPanelWithToggle( isEnabled = isEnabled, onEnabledChanged = { isEnabled = it } ) } }
ในตัวอย่างข้างต้น ทั้ง 3 ส่วนจะห่อหุ้มมากขึ้นและมีคู่น้อยกว่า
ImageWithEnabledOverlay
เพียงแต่อยากรู้ว่าisEnabled
ปัจจุบันเป็นอย่างไร แล้วตอนนี้ ไม่จำเป็นต้องทราบว่ามีControlPanelWithToggle
อยู่ หรือ แม้แต่วิธีที่ควบคุมได้ControlPanelWithToggle
ไม่ทราบว่ามีImageWithEnabledOverlay
อยู่ การแสดงisEnabled
อาจไม่มีเลย อย่างน้อย 1 วิธี และControlPanelWithToggle
ไม่จำเป็นต้องเปลี่ยนแปลงสำหรับผู้ปกครอง ไม่ว่า
ImageWithEnabledOverlay
จะฝังลึกเพียงใดก็ตาม หรือControlPanelWithToggle
เด็กเหล่านั้น สามารถทำให้การเปลี่ยนแปลงเป็นภาพเคลื่อนไหว สลับเนื้อหาหรือส่งต่อเนื้อหาให้เด็กคนอื่นๆ
รูปแบบนี้เรียกว่าการกลับการควบคุมซึ่งอ่านเพิ่มเติมได้
ในเอกสารประกอบของ CompositionLocal
การจัดการการเปลี่ยนแปลงขนาดหน้าจอ
การมีทรัพยากรที่แตกต่างกันสำหรับหน้าต่างขนาดต่างๆ เป็นหนึ่งในวิธีหลักในการ
สร้างเลย์เอาต์ View
ที่ปรับเปลี่ยนตามอุปกรณ์ แม้จะมีตัวเลือกทรัพยากรที่ตรงตามข้อกำหนด
สำหรับการตัดสินใจเรื่องเลย์เอาต์ระดับหน้าจอ Compose จะทำให้เปลี่ยน
ทั้งหมดเป็นโค้ด
ด้วยตรรกะตามเงื่อนไขปกติ โปรดดูข้อมูลเพิ่มเติมในคลาสขนาดหน้าต่าง
นอกจากนี้ โปรดดูหัวข้อรองรับหน้าจอขนาดต่างๆ เพื่อเรียนรู้เทคนิคต่างๆ ที่ Compose มีให้ในการสร้าง UI แบบปรับอัตโนมัติ
การเลื่อนแบบฝังที่มีมุมมอง
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีเปิดใช้งานการทำงานร่วมกันของการเลื่อนที่ฝังไว้ระหว่าง ให้เลื่อนดูเอลิเมนต์และ Composable ที่เลื่อนได้ โดยฝังอยู่ในทั้ง 2 ทิศทาง อ่านแล้ว การทำงานร่วมกันของการเลื่อนที่ซ้อนกัน
เขียนในภาษาRecyclerView
Composable ใน RecyclerView
มีประสิทธิภาพตั้งแต่ RecyclerView
เวอร์ชัน
1.3.0-alpha02 ตรวจสอบว่าใช้เวอร์ชัน 1.3.0-alpha02 เป็นอย่างต่ำ
RecyclerView
เพื่อดูสิทธิประโยชน์เหล่านั้น
การทำงานร่วมกันของ WindowInsets
กับ View
คุณอาจต้องลบล้างส่วนเริ่มต้นเมื่อหน้าจอมีทั้งมุมมองและ เขียนรหัสในลำดับชั้นเดียวกัน ในกรณีนี้ คุณต้องให้ข้อมูลอย่างชัดแจ้งใน แบบใดควรใช้ส่วนแทรก และรายการใดควรละเว้น
ตัวอย่างเช่น หากเลย์เอาต์ด้านนอกสุดเป็นเลย์เอาต์ของ Android View คุณควรทำดังนี้
ใช้ส่วนที่แทรกในระบบมุมมอง และละเว้นสำหรับการเขียน
หรือถ้าเลย์เอาต์ด้านนอกสุดเป็น Composable คุณควรใช้
สิ่งที่แทรกใน Compose และแทรก Composable ของ AndroidView
ตามนั้น
ตามค่าเริ่มต้น ComposeView
แต่ละรายการจะใช้ค่าที่แทรกทั้งหมด
ระดับการใช้งาน WindowInsetsCompat
หากต้องการเปลี่ยนลักษณะการทำงานเริ่มต้นนี้ ให้ตั้งค่า
ComposeView.consumeWindowInsets
ไปยัง false
โปรดอ่านข้อมูลเพิ่มเติมในเอกสารประกอบ WindowInsets
ใน Compose
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- แสดงอีโมจิ
- ดีไซน์ Material 2 ใน Compose
- ส่วนหน้าต่างใน Compose