Jetpack Compose中使用Android View

使用AndroidView创建日历

Kotlin 复制代码
@Composable
fun AndroidViewPage() {
    AndroidView(
        factory = {
            CalendarView(it)
        },
        modifier = Modifier.fillMaxWidth(),
        update = {
            it.setOnDateChangeListener { view, year, month, day ->
                Toast.makeText(
                    view.context, "${year}年${month + 1}月${day}日",
                    Toast.LENGTH_LONG
                ).show()
            }
        }
    )
}

使用Android原生视图需要引入AndroidView组件,factory属性中加入CalendarView日历视图组件,update属性中设置日历的点击事件。

使用WebView

Kotlin 复制代码
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SetJavaScriptEnabled")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WebViewPage() {
    val webView = rememberWebViewWithLifecycle()
    Scaffold(
        content = {
            AndroidView(
                factory = {
                    webView
                }, modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Red),
                update = { webView ->
                    // 设置支持JavaScript
                    val webSettings = webView.settings
                    webSettings.javaScriptEnabled = true
                    webView.loadUrl("https://www.baidu.com")
                }
            )
        }
    )
}

@Composable
fun rememberWebViewWithLifecycle(): WebView {
    val context = LocalContext.current
    val webView = remember {
        WebView(context)
    }
    val lifecycleObserver = rememberWebViewLifecycleObserver(webView)
    val lifecycle = LocalLifecycleOwner.current.lifecycle
    DisposableEffect(lifecycle) {
        lifecycle.addObserver(lifecycleObserver)
        onDispose {
            lifecycle.removeObserver(lifecycleObserver)
        }
    }
    return webView
}

@Composable
private fun rememberWebViewLifecycleObserver(webView: WebView): LifecycleEventObserver =
    remember(webView) {
        LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_RESUME -> webView.onResume()
                Lifecycle.Event.ON_PAUSE -> webView.onPause()
                Lifecycle.Event.ON_DESTROY -> webView.destroy()
                else -> Log.e("WebView", event.name)
            }
        }
    }

使用Android布局

使用Android布局用到了Viewbinding,这里需要引入ui-viewbinding库

bash 复制代码
implementation "androidx.compose.ui:ui-viewbinding:1.5.0-alpha01"

这是android_view.xml原生页面布局

XML 复制代码
<?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">

    <EditText
        android:id="@+id/editName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="30dp"
        android:hint="name" />

    <EditText
        android:id="@+id/editPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="30dp"
        android:hint="password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/btnLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAllCaps="false"
        android:layout_marginTop="30dp"
        android:text="Login" />
</LinearLayout>

Compose中使用原生布局并操作

Kotlin 复制代码
@Composable
fun AndroidViewBindingPage() {
    val context = LocalContext.current
    AndroidViewBinding(
        factory = { inflate, parent, attachToParent ->
            AndroidViewBinding.inflate(inflate, parent, attachToParent)
        },
        modifier = Modifier.fillMaxSize(),
        update = {
            btnLogin.setOnClickListener {
                val name = editName.text.toString().trim()
                val password = editPassword.text.toString().trim()
                toLogin(context, name, password)
            }
        }
    )
}

fun toLogin(context: Context, name: String, password: String) {
    if (name.isEmpty() || password.isEmpty()) {
        Toast.makeText(context, "请输入完整信息", Toast.LENGTH_SHORT).show()
        return
    }
    Toast.makeText(context, "登录信息为:name:${name}, password:${password}", Toast.LENGTH_SHORT)
        .show()
}

引用非常简单,只要通过ViewBinding组件在factory属性中添加页面的引用就行,update属性下对页面进行操作逻辑。

相关推荐
换元不配限11 天前
Jetpack Compose 副作用
compose·jetpack compose·附带效应·副作用·launchedeffect·sideeffect·composable生命周期
Jomurphys11 天前
Compose 适配 - 自适应布局(窗口大小类 WindowSizeClasses、列表详情、辅助窗格)
android·compose
Jomurphys11 天前
Compose 适配 - 分辨率(密度)
android·compose
换元不配限17 天前
Jetpack Compose 状态管理指南
android·状态管理·compose·状态·单向数据流·jetpack compose·状态容器
Android-Flutter1 个月前
android compose shadow 阴影 使用
android·kotlin·compose
Android-Flutter1 个月前
android compose 自定义Painter绘制图形 使用
android·kotlin·compose
Android-Flutter1 个月前
android compose Brush 渐变和着色器 使用
android·kotlin·compose
至乐活着2 个月前
Docker Compose多服务编排实战:从零搭建Node.js+MySQL+Redis全栈应用
docker·微服务·devops·容器编排·compose
le1616162 个月前
Android Compose——尺寸修饰符的调用顺序构成的不同尺寸约束效果
android·compose·modifier
le1616162 个月前
Android Compose Modifier修饰符
android·compose·modifier