Compose 和 Android 传统View 互相调用

news2024/9/23 12:34:16

1. 前言

Compose 具有超强的兼容性,兼容现有的所有代码,Compose 能够与现有 View 体系并存,可实现渐进式替换。这就很有意义了,我们可以在现有项目中一小块一小块逐步地替换Compose,或者在旧项目中实现新的需求的时候,使用Compose
今天,我们就来演示一下,ComposeAndroid View怎么互相调用。

2. Android 传统 View 调用 Compose

2.1 新建传统View体系的Android项目

新建项目的时候选择 Empty Activity

在这里插入图片描述

2.2 项目添加Compose配置

2.2.1 在android代码块添加

appbuild.config android代码块中添加

buildFeatures {
    compose true
}
composeOptions {
    kotlinCompilerExtensionVersion '1.1.1'
}

2.2.2 在dependencies中添加依赖

appbuild.config dependencies代码块中添加

dependencies {
	//...省略...

    def compose_ui_version = '1.1.1' =
    implementation "androidx.compose.ui:ui:$compose_ui_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"

    implementation 'androidx.activity:activity-compose:1.3.1' //kotlin对应版本1.6.20
    implementation 'androidx.compose.material:material:1.1.1'
}

2.3 定义Compose函数

MainActivity.kt中定义Compose函数

@Composable
fun ComposeContent() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Hello world!")
    }
}

2.4 修改xml文件

activity_main.xml中添加androidx.compose.ui.platform.ComposeView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

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

</LinearLayout>

2.5 关联Compose函数

MainActivity.kt中,先通过findViewById找到ComposeView,然后通过composeView.setContent将Android 传统View和Compose建立关联。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val composeView : ComposeView = findViewById(R.id.compose_view)
    composeView.setContent {
        ComposeContent()
    }
}

2.6 运行项目

可以发现界面显示如下,成功在传统View项目中调用了Compose

在这里插入图片描述

3. Compose中调用Android View

3.1 调用传统View的日历

3.1.1 使用AndroidView

@Composable内使用: androidx.compose.ui.viewinterop.AndroidView,然后在factory里面返回原生View即可

@Composable
fun AndroidViewPage() {
    AndroidView(factory = {
        CalendarView(it)
    }, modifier = Modifier.fillMaxWidth(), update = {
        it.setOnDateChangeListener { view, year, month, day ->
            Toast.makeText(view.context, "${year}${month}${day}日", Toast.LENGTH_SHORT).show()
        }
    })
}

3.1.2 显示效果如下

在这里插入图片描述

3.2 调用传统View的WebView

3.2.1 添加网络权限

首先需要在AndroidManifest.xml中添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

3.2.2 首先要注册WebView的生命周期

@Composable
private fun rememberWebViewLifecycleObserver(webView: WebView): LifecycleEventObserver {
    return remember(webView) {
        LifecycleEventObserver { _, event ->
            run {
                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)
                }
            }
        }
    }
}

3.2.3 创建有状态的WebView

创建有状态的WebView,并注册生命周期

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

3.2.4 调用Android View

@Composable
fun WebViewPage() {
    //创建有状态的WebView,并注册生命周期
    val webView = rememberWebViewWIthLifecycle()
    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")
    })
}

3.2.5 显示效果如下所示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式之外观模式

Facade design pattern 外观模式的概念、外观模式的结构、外观模式的优缺点、外观模式的使用场景、外观模式的实现示例、外观模式的源码分析 1、外观模式的概念 外观模式&#xff0c;为多个复杂的子系统提供一个统一的接口&#xff0c;使得这些子系统更加容易被访问。在现有的…

【AI with ML】第 11 章 :对序列模型使用卷积和递归方法

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

SAP Gateway Foundation 里的 batch 操作

SAP Gateway Foundation (SAP_GWFND) 是一个在 SAP NetWeaver 中可用的软件组件。 SAP Gateway Foundation 提供开发和生成工具来为各种客户端开发工具创建 OData 服务。 简而言之&#xff0c;它在应用程序或 SAP Business Suite 数据与目标客户、平台和编程框架之间建立连接。…

核心面试题:MVCC、间隙锁、Undo Log链、表级锁、行级锁、页级锁、共享锁、排它锁、记录锁等等

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…

网页初学者,如何使用VS2005搭建编程环境(JavaScript及ASP调试)

一直想学一下网页编程&#xff0c;但是感觉要学的东西太多了。也没有人指导。只好一个人摸索。 尝试了一些常用的网页编程技术。得出自己的总结&#xff0c;写在这里做一个备份。 本文写个自己&#xff0c;也作为和我一样的初学者一个参考。 【工具准备】 一、服务器端学什…

大数据的基础知识上(大数据的概念和生态、linux系统与命令、虚拟机导入、虚拟机额配置和联网)

目录一、数据分析的方向二、数据分析步骤1.明确分析目的和思路2.数据传输收集过程3.数据处理4.数据分析5.数据展现6.报告撰写三、数据是什么 大数据时代大数据的应用有哪些四、分布式和集群1.概念&#x1f3a1;&#xff08;by the way&#xff09;大数据生态系统&#x1f3a1;&…

【Three.js入门】一文带你入坑前端3Dの妙妙屋

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

消息队列 - RabbitMQ - 拓展

1. Message 状态 Message 在投递时&#xff0c;如果当前 Queue 没有 Message&#xff0c;且有 Consumer 已经订阅了这个 Queue&#xff0c;那么该 Message 会直接发送给 Consumer&#xff0c;不会经过 Queue 存储 Message 的这一步 当 Message 无法直接投递给 Consumer 时&am…

【大数据技术Hadoop+Spark】Spark RDD创建、操作及词频统计、倒排索引实战(超详细 附源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、RDD的创建 Spark可以从Hadoop支持的任何存储源中加载数据去创建RDD&#xff0c;包括本地文件系统和HDFS等文件系统。我们通过Spark中的SparkContext对象调用textFile()方法加载数据创建RDD。 1、从文件系统加载数据创…

基于 Tensorflow 2.x 实现多层卷积神经网络,实践 MNIST 手写数字识别

一、MNIST 数据集 上篇文章中使用了Tensorflow 2.x 搭建了对层的 BP 神经网络&#xff0c;经过训练后发现准确率只有 96.8% 对于单环境的图片识别场景来说&#xff0c;还是有点偏低&#xff0c;本文使用多层的卷积代替BP网络中的隐藏层对模型进行优化。 下面是上篇文章地址&am…

C语言重点解剖第12课笔记

1.int* a,b; a和b的类型不一样&#xff0c; a是指针&#xff0c;b是整型。 typedef int* int_p; int_p a,b; 或者int* a,*b; 这样写的话&#xff0c;a和b都是指针类型。 #define int_p int*;这是纯粹的文本替换。 typedef定义之后是一种独立类型。 2.大部分注释都换成了…

Linux网络协议之HTTP协议(应用层)

Linux网络协议之HTTP协议(应用层) 文章目录Linux网络协议之HTTP协议(应用层)1.HTTP协议的概念2.HTTP协议中URL的理解3.HTTP协议的数据流4.HTTP协议的格式4.1 HTTP请求格式4.2 HTTP响应格式5.HTTP协议格式图解6.HTTP协议版本7.HTTP协议请求方法7.1 GET方法&#xff1a;获取资源7…

OWASP API安全Top 10

文章目录API1-失效的对象级授权API2-失效的用户认证API3-过度的数据暴露API4-缺乏资源和速率控制API5-失效的功能级授权API6-批量分配API7-安全性配置错误API8-注入API9-资产管理不当API10-日志记录和监控不足在API安全发展的过程中&#xff0c;除了各大安全厂商和头部互联网企…

计算机基础学习笔记:操作系统篇之硬件结构,CPU的基本工作原理

一、CPU的是如何运行程序的&#xff1f; 本文知识来源小林Coding阅读整理思考&#xff0c;原文链接请见以下&#xff1a; https://xiaolincoding.com/os/1_hardware/how_cpu_run.html#图灵机的工作方式 问题引入 程序的执行过程&#xff1f;例如 12 的具体过程是怎么样的&…

Windows VS2015 cmake编译Gtest并进行测试

1.下载Gtest 下载网址&#xff1a;https://github.com/google/googletest/releases 也可以直接使用下载好的附件 解压&#xff0c;放到一个目录中&#xff0c;演示所用&#xff0c;直接存放D盘了。 2.使用CMake生成vs编译工程 选好下图中两个路径&#xff0c;点击Configure…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (8)- AWBlock

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

玩以太坊链上项目的必备技能(OOP-接口-Solidity之旅十一)

接口&#xff08;interface&#xff09; 我们知道在Java里接口是特殊的抽象类&#xff0c;限制多于抽象类&#xff0c;但随着Java版本的更新&#xff0c;Java中的接口是越来越趋于抽象类了&#xff08;这样说&#xff0c;可能有点不妥&#xff0c;因为接口本就是特殊的抽象类&…

自己整理的Java面试题(下)

目录五.Java框架部分Spring1.Spring中的拦截器&#xff0c;过滤器组件介绍&#xff1f;2.说一下spring的IOC&#xff1f;3.Spring中的异常处理&#xff1a;4.jdk动态代理和cglib动态代理&#xff1a;5.Spring Bean生命周期&#xff1a;6.Spring IOC原理&#xff1a;7.BeanFacto…

RK3568平台开发系列讲解(Camera篇)Camera API v2框架

🚀返回专栏总目录 文章目录 一、Camera API v2框架二、preview流程三、核心模块沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇讲介绍 Camera API v2框架。 一、Camera API v2框架 应用框架:应用代码位于应用框架级别,它使用 Camera 2 API 与相机硬件进行交互…

【正点原子I.MX6U-MINI】u-boot过程移植详解

正点原子的I.MX6ULL开发板参考的是NXP官方的I.MX6ULL EVK开发板做的硬件。 Linux的移植要复杂的多&#xff0c;在移植Linux之前我们需要先移植一个 bootloader 代码&#xff0c;这个 bootloader 代码用于启动Linux 内核&#xff0c;bootloader有很多&#xff0c;常用的就是 U-…