iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0
Mobile Development

Jetpack Compose 從心開始系列 第 23

Jetpack Compose 從心開始 Day23 - View 和 Compose

  • 分享至 

  • xImage
  •  

前言

    Jetpack Compose 在設計之初就考慮了 View 互通性。 這項功能意味著您可以將現有的 View 應用程式遷移至 Compose,同時仍然可以建構新功能。

什麼是 View 和 Compose?

  • View: Android傳統的UI工具組,使用XML布局文件和Java/Kotlin程式碼來建立使用者介面。
  • Compose: Google推出的全新UI工具組,使用宣告式語法,以Kotlin為基礎,讓開發者能夠更直覺地構建UI。

為什麼要將 View 和 Compose 結合?

  • 漸進式遷移: 並非所有專案都能一次性完全遷移到Compose,將Compose整合到現有的View專案中,可以逐步替換部分UI,降低遷移風險。
  • 利用既有元件: 對於Compose尚未支援的複雜元件或第三方庫,可以繼續使用View。
  • 混合使用: 根據不同需求,選擇最適合的工具來構建UI。

如何在 View 中使用 Compose?

新增 Compose 依附元件

在你的 app/build.gradle 檔案中添加 Compose 的程式庫

android {
    buildFeatures {
        viewBinding true
        compose true
    }
    // ... 其他設定
}

composeOptions {
    kotlinCompilerExtensionVersion = "1.5.1"
}

dependencies {
    implementation(platform("androidx.compose:compose-bom:2023.06.01"))
    // other dependencies
    // Compose
    implementation("androidx.activity:activity-compose:1.7.2")
    implementation("androidx.compose.material3:material3")
    implementation("com.google.accompanist:accompanist-themeadapter-material3:0.28.0")

    debugImplementation("androidx.compose.ui:ui-tooling")
}

在 XML 布局中加入 ComposeView

  • 創建 ComposeView: 在 XML 布局中加入一個 ComposeView 元素,它將作為 Compose UI 的容器。
  • 在 ComposeView 中撰寫 Compose 程式碼: 使用 Compose 的方式來構建 UI。

Fragment 中的 ComposeView

<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/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

  <androidx.compose.ui.platform.ComposeView
      android:id="@+id/compose_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
</LinearLayout>

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
    }
}

https://ithelp.ithome.com.tw/upload/images/20241003/20121643l79c6O8wkU.png

在 Compose 中使用 View

<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" />
@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}

參考

https://developer.android.com/courses/android-basics-compose/unit-8?hl=zh-tw


上一篇
Jetpack Compose 從心開始 Day22 - 使用 WorkManager 安排工作
下一篇
Jetpack Compose 從心開始 Day24 - 配合不同的螢幕大小進行調整
系列文
Jetpack Compose 從心開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言