ITmob-Ly
发布于 2023-07-10 / 134 阅读
0

Jetpack Compose 和 Android View 的互相操作

将整个项目迁移到 Compose 中可能很困难,幸运的是 Jetpack Compose 提供了Compose 和 传统视图/View 互相操作 API 来在现有 XML 视图中使用 Compose,以便可以慢慢迁移到 Compose。Jetpack Compose 也提供了 API 来实现在 Compose 中使用传统视图的 API。

View 中嵌入 Compose

Jetpack Compose 提供了一个 ComposeView,我们可以在 XML 中使用它,然后在 View 中使用 ComposeViewsetContent 方法将 Composable 方法来绘制 UI。

  1. 在布局中加一个 ComposeView

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <androidx.compose.ui.platform.ComposeView
            android:id="@+id/composeView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    
  2. 获得 ComposeView 添加 Composable 方法

    val composeView = findViewById<ComposeView>(R.id.compose_view)
    composeView.setContent {
        Text(text = "Hello https://itmob.cn")
    }
    

当然不使用 XML 布局文件,使用代码动态添加也是可以的:

package cn.itmob.example

import android.os.Bundle
import android.widget.LinearLayout
import android.widget.LinearLayout.VERTICAL
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.ui.platform.ComposeView

class SampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_views)

        setContentView(
            LinearLayout(this).apply {
                orientation = VERTICAL
                addView(
                    // Add ComposeView
                    ComposeView(baseContext).apply {
                        id = R.id.compose_view
                        setContent {
                            MaterialTheme {
                                Text("androidx.compose.material.Text")
                            }
                        }
                    },
                )
                // Add TextView
                addView(
                    TextView(context).apply { text = "android.widget.TextView" },
                )
            },
        )
    }
}

Add ComposeView in Android View

Compose 中嵌入 View

Jetpack Compose 是独立于传统的 Android View 系统,但在 Compose 中可以也使用 View(及 android.view.View 的子类)。

为什么要在 Compose 中使用 Android View:

  1. WebView,AdView 等还没有原生的 Compose 版本
  2. 已实现的自定义 View 不想用 Compose 重写,可以直接嵌入到 Compose 中

这里以在 Compose 中嵌入 android.widget.Button 为例:

@Composable
fun AndroidViewSample() {
    AndroidView(
        factory = { context ->
            android.widget.Button(context).apply { text = "Using android.widget.Button in Compose" }
        },
    )
}

Add AndroidView in Composable function