Jetpack Compose中使用Android View

news/2024/5/17 17:17:23 标签: Compose, Android布局, Compose与Android

使用AndroidView创建日历

@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

 

@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库

implementation "androidx.compose.ui:ui-viewbinding:1.5.0-alpha01"

这是android_view.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中使用原生布局并操作

@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属性下对页面进行操作逻辑。


http://www.niftyadmin.cn/n/5292160.html

相关文章

在wps里导入Mathtype、改变字体

1 在wps里导入Mathtype 开发工具--加载项 2. 在“模板和加载项”窗口中再点击“添加” 3.找到mathtype安装路径下面的“OfficeSupprot”&#xff0c;这时会看到有“32”和“64”两个文件夹&#xff0c;分别对应WPS软件的系统&#xff08;任务管理器可以直接查看wps版本&#x…

大数据与人工智能|万物皆算法(第三节)

要点一&#xff1a;数据与智能的关系 1. 一切的核心都是数据&#xff0c;数据和智能之间是密切相关的。 数据是对客观现实的描述&#xff0c;而信息是数据转化而来的。 例如&#xff0c;24是数据&#xff0c;但说“今天的气温是24摄氏度”是信息&#xff0c;而说“班可以分成24…

防火墙什么用,软件防火墙与硬件防火墙有什么不一样

防火墙是一种网络安全技术&#xff0c;通过有机结合各类用于安全管理与筛选的软件和硬件设备&#xff0c;在计算机网络的内、外网之间构建一道相对隔绝的保护屏障&#xff0c;以保护用户资料与信息的安全性。 防火墙的作用的详细说明&#xff1a; 1.访问控制&#xff1a;防火…

Spring AOP—深入动态代理 万字详解(通俗易懂)

目录 一、前言 二、动态代理快速入门 1.为什么需要动态代理&#xff1f; : 2.动态代理使用案例&#xff1a; 3.动态代理的灵活性 : 三、深入动态代理 1.需求 : 2.实现 : 2.1 接口和实现类 2.2 提供代理对象的类 2.3 测试类 3.引出AOP : 四、总结 一、前言 第四节内容&…

flutter dio使用proxyman抓包进行网络调试

证书 wifi 手机和电脑连上同一个wifi&#xff0c;并且手机wifi使用代理&#xff0c;代理地址为电脑的ip和proxyman设置的监听端口 代码 import package:dio/dio.dart; import package:dio/io.dart; import dart:io;class ProxyUtil {static String proxyIP "";st…

HTML制作暴雨特效

🎀效果展示 🎀代码展示 <body> <!-- partial:index.partial.html --> <canvas id="canvas-club">

垃圾收集器与内存分配策略

内存分配和回收原则 对象优先在Eden区分配 大对象直接进入老年代 长期存活的对象进入老年代 什么是内存泄漏 不再使用的对象在系统中未被回收&#xff0c;内存泄漏的积累可能会导致内存溢出 自动垃圾回收与手动垃圾回收 自动垃圾回收&#xff1a;由虚拟机来自动回收对象…

【C语言】数据结构——排序(一)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——数据结构学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;数组打印与交换1. 插入排序1.1 直接插入排序1.1.1 基本思想1.1.2 实现代码1.1.3 图解 1.2 希尔排序1.2.1…