คุณรวมลำดับชั้นของ Android View ไว้ใน UI ของการเขียนได้ วิธีนี้
โดยเฉพาะในกรณีที่คุณต้องการใช้องค์ประกอบ UI ที่ยังไม่มีใน
เขียน เช่น
AdView
วิธีการนี้ยังช่วยให้คุณสามารถนำมุมมองที่กำหนดเองที่คุณอาจออกแบบไว้มาใช้ใหม่ได้ด้วย
หากต้องการรวมองค์ประกอบข้อมูลพร็อพเพอร์ตี้หรือลำดับชั้น ให้ใช้ AndroidView
Composable AndroidView
ผ่านการตรวจสอบ lambda ที่ส่งกลับ
View
AndroidView
ยังมี update
Callback ซึ่งเรียกใช้เมื่อมุมมองขยายออก การจัดองค์ประกอบ AndroidView
ใหม่
เมื่อใดก็ตามที่ State
อ่านภายใน Callback มีการเปลี่ยนแปลง AndroidView
เช่นเดียวกับหลายรายการ
Composable ในตัวอื่นๆ จะใช้พารามิเตอร์ Modifier
ที่ใช้ได้
เช่น เพื่อกำหนดตำแหน่งใน Composable หลัก
@Composable fun CustomView() { var selectedItem by remember { mutableStateOf(0) } // Adds view to Compose AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> // Creates view MyView(context).apply { // Sets up listeners for View -> Compose communication setOnClickListener { selectedItem = 1 } } }, update = { view -> // View's been inflated or state read in this block has been updated // Add logic here if necessary // As selectedItem is read here, AndroidView will recompose // whenever the state changes // Example of Compose -> View communication view.selectedItem = selectedItem } ) } @Composable fun ContentExample() { Column(Modifier.fillMaxSize()) { Text("Look at this CustomView!") CustomView() } }
AndroidView
พร้อมการเชื่อมโยงมุมมอง
ในการฝังเค้าโครง XML ให้ใช้
AndroidViewBinding
API ซึ่งให้บริการโดยไลบรารี androidx.compose.ui:ui-viewbinding
ถึง
ในกรณีเช่นนี้ โปรเจ็กต์ต้องเปิดใช้การเชื่อมโยงข้อมูลพร็อพเพอร์ตี้
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView
ในรายการแบบ Lazy Loading
หากคุณใช้ AndroidView
ในรายการแบบ Lazy Loading (LazyColumn
, LazyRow
,
Pager
ฯลฯ) ให้พิจารณาใช้ AndroidView
ใช้งานโอเวอร์โหลดในเวอร์ชัน 1.4.0-rc01 โอเวอร์โหลดนี้ทำให้ Compose สามารถใช้ซ้ำได้
อินสแตนซ์ View
ที่อยู่ด้านล่างเมื่อมีการใช้การเรียบเรียงที่มีองค์ประกอบซ้ำตามที่เป็น
เช่น รายการแบบ Lazy
โอเวอร์โหลดของ AndroidView
นี้จะเพิ่มพารามิเตอร์อีก 2 รายการ ได้แก่
onReset
- มีการเรียกใช้ Callback เพื่อส่งสัญญาณว่าView
กำลังจะถูกเรียก ที่ใช้ซ้ำได้ ต้องระบุค่านี้เพื่อเปิดใช้การใช้ข้อมูลพร็อพเพอร์ตี้ซ้ำonRelease
(ไม่บังคับ) - มีการเรียกใช้ Callback เพื่อส่งสัญญาณว่าView
มี ออกจากการเรียบเรียงแล้วและจะไม่นำไปใช้ซ้ำอีก
@OptIn(ExperimentalComposeUiApi::class) @Composable fun AndroidViewInLazyList() { LazyColumn { items(100) { index -> AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> MyView(context) }, update = { view -> view.selectedItem = index }, onReset = { view -> view.clear() } ) } } }
ส่วนย่อยใน Compose
ใช้ AndroidViewBinding
Composable เพื่อเพิ่ม Fragment
ใน Compose
AndroidViewBinding
มีการจัดการเฉพาะส่วนย่อย เช่น การนำพารามิเตอร์
Fragment เมื่อ Composable ออกจากการเรียบเรียง
ซึ่งทำได้ด้วยการเพิ่ม XML ที่มี FragmentContainerView
เป็นเจ้าของ Fragment
ของคุณ
ตัวอย่างเช่น หากกําหนด my_fragment_layout.xml
ไว้ คุณสามารถใช้
ในลักษณะนี้ขณะแทนที่แอตทริบิวต์ XML android:name
ด้วย
ชื่อชั้นเรียนของ Fragment
:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container_view" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.example.compose.snippets.interop.MyFragment" />
ขยายส่วนย่อยนี้ใน Compose ดังนี้
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
หากต้องการใช้ส่วนย่อยหลายรายการในเลย์เอาต์เดียวกัน ให้ตรวจสอบว่ามี
กำหนดรหัสที่ไม่ซ้ำกันสำหรับแต่ละ FragmentContainerView
การเรียกใช้เฟรมเวิร์ก Android จาก Compose
Compose จะทำงานภายในคลาสเฟรมเวิร์กของ Android ตัวอย่างเช่น มีการโฮสต์
ในคลาส Android View เช่น Activity
หรือ Fragment
และอาจใช้ Android
คลาสของเฟรมเวิร์ก เช่น Context
, ทรัพยากรของระบบ
Service
หรือ BroadcastReceiver
ดูข้อมูลเพิ่มเติมเกี่ยวกับทรัพยากรของระบบได้ที่ทรัพยากรใน Compose
การเรียบเรียงท้องถิ่น
CompositionLocal
คลาสอนุญาตให้ส่งข้อมูลโดยปริยายผ่านฟังก์ชัน Composable คือ
ซึ่งปกติแล้วจะมีค่าในโหนดใดโหนดหนึ่งของโครงสร้าง UI ค่าดังกล่าวสามารถ
ใช้โดยองค์ประกอบสืบทอดที่ประกอบกันได้โดยไม่ต้องประกาศ CompositionLocal
เป็นพารามิเตอร์ในฟังก์ชัน Composable
ใช้ CompositionLocal
เพื่อเผยแพร่ค่าสำหรับประเภทเฟรมเวิร์ก Android ใน
Compose เช่น Context
, Configuration
หรือ View
ที่มีการเขียน
จะใช้โฮสต์กับ
LocalContext
,
LocalConfiguration
หรือ
LocalView
โปรดทราบว่าชั้นเรียน CompositionLocal
จะมี Local
นำหน้าเพื่อประสิทธิภาพที่ดีขึ้น
การค้นพบได้ด้วยการใช้การเติมข้อความอัตโนมัติใน IDE
เข้าถึงค่าปัจจุบันของ CompositionLocal
โดยใช้ current
ตัวอย่างเช่น โค้ดด้านล่างแสดงข้อความโทสต์โดยการระบุ
LocalContext.current
ลงในเมธอด Toast.makeToast
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
ดูตัวอย่างที่สมบูรณ์มากขึ้นได้จากกรณีศึกษา: BroadcastReceivers ที่ตอนท้ายของ เอกสาร
การโต้ตอบอื่นๆ
หากไม่มีการกำหนดยูทิลิตีไว้สำหรับการโต้ตอบที่คุณต้องการ แนวทางปฏิบัติที่ดีที่สุด คือการปฏิบัติตามหลักเกณฑ์ทั่วไปของการเขียน ข้อมูลไหลลง เหตุการณ์ไหลขึ้น (กล่าวถึงมากขึ้นในการคิด ใน Compose) ตัวอย่างเช่น Composable นี้ เปิดกิจกรรมอื่น เช่น
class OtherInteractionsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // get data from savedInstanceState setContent { MaterialTheme { ExampleComposable(data, onButtonClick = { startActivity(Intent(this, MyActivity::class.java)) }) } } } } @Composable fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) { Button(onClick = onButtonClick) { Text(data.title) } }
กรณีศึกษา: Broadcast Receiver
สำหรับตัวอย่างฟีเจอร์ที่ใช้ได้จริงมากขึ้น คุณอาจต้องการย้ายข้อมูลหรือติดตั้งใช้งาน
ในการเขียน และแสดง CompositionLocal
และ ด้านข้าง
ของเอฟเฟกต์ สมมติว่า
BroadcastReceiver
ต้องลงทะเบียนจาก
ฟังก์ชันที่ประกอบกันได้
โซลูชันนี้จะใช้ LocalContext
เพื่อใช้บริบทปัจจุบัน และ
ผลข้างเคียงของ rememberUpdatedState
และ DisposableEffect
@Composable fun SystemBroadcastReceiver( systemAction: String, onSystemEvent: (intent: Intent?) -> Unit ) { // Grab the current context in this part of the UI tree val context = LocalContext.current // Safely use the latest onSystemEvent lambda passed to the function val currentOnSystemEvent by rememberUpdatedState(onSystemEvent) // If either context or systemAction changes, unregister and register again DisposableEffect(context, systemAction) { val intentFilter = IntentFilter(systemAction) val broadcast = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { currentOnSystemEvent(intent) } } context.registerReceiver(broadcast, intentFilter) // When the effect leaves the Composition, remove the callback onDispose { context.unregisterReceiver(broadcast) } } } @Composable fun HomeScreen() { SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus -> val isCharging = /* Get from batteryStatus ... */ true /* Do something if the device is charging */ } /* Rest of the HomeScreen */ }
ขั้นตอนถัดไป
ตอนนี้คุณทราบ API การทำงานร่วมกันเมื่อใช้ Compose ในข้อมูลพร็อพเพอร์ตี้และเมื่อใช้ Compose แล้ว ในทางกลับกัน ให้ไปที่หน้าข้อควรพิจารณาอื่นๆ เพื่อเรียนรู้เพิ่มเติม
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ข้อควรพิจารณาอื่นๆ
- ผลข้างเคียงใน Compose
- ข้อมูลที่กำหนดขอบเขตเฉพาะพื้นที่ด้วย CompositionLocal