您可以在採用基於 View 設計的現有應用程式中,新增以 Compose 為基礎的 UI。
如要建立以 Compose 為基礎的新畫面,請讓活動呼叫 setContent()
方法,然後視需要傳遞任何可組合項。
class ExampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // In here, we can call composables! MaterialTheme { Greeting(name = "compose") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
這段程式碼看起來就像 Compose-only App中會出現的寫法。
ComposeView
的 ViewCompositionStrategy
當檢視畫面從視窗卸離時,Compose 預設會處置 Composition。Compose UI View
類型 (例如 ComposeView
和 AbstractComposeView
) 是使用ViewCompositionStrategy
來定義此行為。
Compose 在預設情況下是使用 DisposeOnDetachedFromWindowOrReleasedFromPool
策略。但在某些使用 Compose UI View
類型的情況下,這個預設值是不適合的:
Fragment。Composition 必須遵循 Fragment 的檢視畫面生命週期,Compose UI
View
類型才能儲存狀態。轉換。只要在轉換中使用 Compose UI
View
,View 就會在轉換開始 (而非轉換結束) 時從視窗卸離,導致可組合項仍顯示在畫面上時就處置自身狀態。您自己的生命週期管理自訂
View
。
在上述某些情況下,除非您手動呼叫 AbstractComposeView.disposeComposition
,否則應用程式將從 Composition 執行個體緩慢地流失記憶體。
請設定其他策略、或透過呼叫 setViewCompositionStrategy
方法,建立自己的策略,自動地處置不再需要的 Composition。例如,lifecycle
遭刪除時,DisposeOnLifecycleDestroyed
策略會處置Composition。此策略適用於與已知 LifecycleOwner
同樣具有 1 對 1 關係的 Compose UI View
類型。如果 LifecycleOwner
為未知,您可以使用 DisposeOnViewTreeLifecycleDestroyed
。
如要查看這個 API 的實際應用情形,請參閱 Fragment 中的 ComposeView
。
Fragment 中的 ComposeView
如要在片段或現有的 View 版面配置中加入 Compose UI 內容,請使用 ComposeView
並呼叫其 setContent()
方法。ComposeView
是 Android View
。
您可將 ComposeView
和其他的 View
一樣地放在 XML 版面配置中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello Android!" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
在 Kotlin 原始碼中,從 XML 定義的版面配置資源加載版面配置。然後使用 XML ID 取得 ComposeView
,並設定最適合代管 View
的 Composition 策略,並呼叫 setContent()
以使用 Compose。
class ExampleFragment : Fragment() { private var _binding: FragmentExampleBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentExampleBinding.inflate(inflater, container, false) val view = binding.root binding.composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } override fun onDestroyView() { super.onDestroyView() _binding = null } }
圖 1. 這個程式碼會顯示在 View UI 階層中新增 Compose 元素的程式碼輸出內容。「Hello Android!」文字會以 TextView
小工具顯示。「您好 Compose!」文字會顯示Compose 文字元素。
假如您使用 Compose 建構全螢幕畫面,可以直接在片段中加入 ComposeView
,避免單獨使用 XML 版面配置檔案。
class ExampleFragmentNoXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { MaterialTheme { // In Compose world Text("Hello Compose!") } } } } }
在同一個版面配置中有多個 ComposeView
執行個體
如果在同一個版面配置中有多個 ComposeView
元素,則每個元素都必須有專屬 ID,savedInstanceState
才能正常運作。
class ExampleFragmentMultipleComposeView : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = LinearLayout(requireContext()).apply { addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_x // ... } ) addView(TextView(requireContext())) addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_y // ... } ) } }
res/values/ids.xml
檔案已定義 ComposeView
ID:
<resources>
<item name="compose_view_x" type="id" />
<item name="compose_view_y" type="id" />
</resources>
後續步驟
現在您已瞭解互通性 API 的相關資訊,能夠在 View 中使用 Compose,接著請瞭解如何在 Compose 中使用 View。