Jetpack Compose 从入门到入门(十)

2023-05-16

本篇介绍如何将Jetpack Compose 添加到已有应用中,毕竟大多数情况都是在现有项目中使用。

Jetpack Compose 旨在配合既有的基于 View 的界面构造方式一起使用。如果您要构建新应用,最好的选择可能是使用 Compose 实现整个界面。但是,如果您要修改现有应用,那么请不要一次性迁移整个应用,而是可以将 Compose 与现有的界面设计实现相结合。

要将 Compose 与基于 View 的界面结合使用,有两种主要方法:

  • 将 Compose 元素添加到现有界面中。具体方式是创建基于 Compose 的全新页面,或者将 Compose 元素添加到现有的 activity、fragment 或 View 布局中。
  • 将基于 View 的界面元素添加到可组合函数中。如此一来,您便可在基于 Compose 的设计中添加 Android View。

1.设置您的开发环境

首先就是引入项目中的配置,这部分可以参加本系列第一篇的项目配置。需要注意的是各版本的最低要求。

例如你使用Compose 1.2.0版本,compileSdk需要最低到32、kotlin版本最低1.7.0,gradle最低7.2.0。还有Compose 需要的依赖,例如使用 activity-compose 依赖时,androidx.activity 最低为 1.3.0。

具体需要根据项目的情况来选择相应版本,不要因为引入 Compose破坏了项目原本的稳定运行。

2.Interoperability API

1.View 中的 Compose

如果是创建基于 Compose 的全新页面,那就相对比较简单,就是我们第一篇的内容,activity 调用 setContent() 方法,传递相应的@Composable函数。

我们看一个例子,如何将 Compose 元素添加到现有fragment布局中。首先将 ComposeView 添加到 XML 布局中:

<?xml version="1.0" encoding="utf-8"?>
<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/hello_world"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello Android!" />

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

</LinearLayout>

代码获取 ComposeView,设置适合宿主 View 的组合策略,并调用 setContent()以使用 Compose

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 {
            setViewCompositionStrategy(DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                // In Compose world
                MaterialTheme {
                    Text("Hello Compose!")
                }
            }
        }
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

调用 setViewCompositionStrategy 方法设置其他策略或创建自己的策略。例如DisposeOnLifecycleDestroyed 策略会在 lifecycle 被销毁时处理 Compose。当 LifecycleOwner 未知时,可以使用 DisposeOnViewTreeLifecycleDestroyed

如果同一布局中存在多个 ComposeView 元素,每个元素必须具有唯一的 ID 才能使 savedInstanceState 发挥作用。ComposeView ID 在 res/values/ids.xml 文件中进行定义。

class ExampleFragment : Fragment() {

  override fun onCreateView(...): View = LinearLayout(...).apply {
      addView(ComposeView(...).apply {
          id = R.id.compose_view_x
          ...
      })
      addView(TextView(...))
      addView(ComposeView(...).apply {
          id = R.id.compose_view_y
          ...
      })
    }
  }
}

2.Compose 中的 View

Compose 界面中添加 Android View ,比如项目中已有的自定义View等。这样就不需要重新去用Compose实现一遍了。

实现起来很简单,使用AndroidView。系统会向 AndroidView 传递一个返回 View 的 lambda。AndroidView 还提供了在View填充时被调用的 update 回调。

@Composable
fun CustomView() {
    val selectedItem = remember { mutableStateOf(0) }

    // Adds view to Compose
    AndroidView(
        modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
        factory = { context ->
            // Creates custom view
            CustomView(context).apply {
                myView.setOnClickListener {
                    selectedItem.value = 1
                }
            }
        },
        update = { view ->
            // 视图已被填充或读取的状态更新
            // 当selectedItem在这里读取时,AndroidView将在状态改变时重新组合
            view.coordinator.selectedItem = selectedItem.value
        }
    )
}

@Composable
fun ContentExample() {
    Column(Modifier.fillMaxSize()) {
        Text("Look at this CustomView!")
        CustomView()
    }
}

如需嵌入XML布局,可以使用 androidx.compose.ui:ui-viewbinding 库提供的 AndroidViewBinding API。

@Composable
fun AndroidViewBindingExample() {
    AndroidViewBinding(ExampleLayoutBinding::inflate) {
        exampleView.setBackgroundColor(Color.GRAY)
    }
}

3.Compose 中的 fragment

添加Fragment可以使用FragmentContainerView ,将XML 属性 android:name 设置为 Fragment 的类名称。

例如定义 my_fragment_layout.xml

<androidx.fragment.app.FragmentContainerView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/fragment_container_view"
  android:layout_height="match_parent"
  android:layout_width="match_parent"
  android:name="com.example.MyFragment" />

然后就可以获取相应的Fragment:

@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}

3.共享使用

逐步迁移到 Compose的过程中,可能需要在ComposeView 系统中使用共同的界面元素。比如我用Compose写了一个名为CallToActionButton的Button,如何在 ComposeView中都使用?

@Composable
fun CallToActionButton(
    text: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    Button(
        colors = ButtonDefaults.buttonColors(
            backgroundColor = MaterialTheme.colors.secondary
        ),
        onClick = onClick,
        modifier = modifier,
    ) {
        Text(text)
    }
}

办法是需要创建一个继承 AbstractComposeView 的自定义VIew封装容器。

class CallToActionViewButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : AbstractComposeView(context, attrs, defStyle) {

    var text by mutableStateOf<String>("")
    var onClick by mutableStateOf<() -> Unit>({})

    @Composable
    override fun Content() {
        YourAppTheme {
            CallToActionButton(text, onClick)
        }
    }
}

具体调用:

class ExampleActivity : Activity() {

    private lateinit var binding: ActivityExampleBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityExampleBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.callToAction.apply {
            text = getString(R.string.something)
            onClick = { /* Do something */ }
        }
    }
}

4.Compose 调用 Android 框架

如果需要利用 Android 框架类,比如ContextService,可以使用 CompositionLocalcurrent属性访问前者当前值。例如,以下代码通过向 Toast.makeToast 方法提供 LocalContext.current 来显示消息框消息。

@Composable
fun ToastGreetingButton(greeting: String) {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show()
    }) {
        Text("Greet")
    }
}

除了LocalContext外,还有LocalLifecycleOwnerLocalView 等供我们直接使用。


对于Compose来说,单向数据流模式非常适合它。所以MVI架构是一种不错的选择,后面有时间的话可以说说这块。

那么本篇到此结束,本系列也基本完成。官方文档总的来说还是比较详细的,本系列也算是官方文档的一个个人实践总结,希望可以帮到你。

看完后是不是从入门到入门,哈哈,具体还是需要多实践。

5.参考

  • 官方文档 - 在应用中采用 Compose
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jetpack Compose 从入门到入门(十) 的相关文章

  • Jetpack Compose 从入门到入门(八)

    接着上一篇的动画部分 xff0c 本篇主要是自定义动画与Animatable AnimationSpec 上一篇中 xff0c 出现了多次animationSpec属性 xff0c 它是用来自定义动画规范的 例如 xff1a span cl
  • Jetpack Compose 从入门到入门(九)

    本篇是Compose的手势部分 点击 添加clickable修饰符就可以轻松实现元素的点击 此外它还提供无障碍功能 xff0c 并在点按时显示水波纹效果 span class token annotation builtin 64 Comp
  • Jetpack Compose 从入门到入门(十)

    本篇介绍如何将Jetpack Compose 添加到已有应用中 xff0c 毕竟大多数情况都是在现有项目中使用 Jetpack Compose 旨在配合既有的基于 View 的界面构造方式一起使用 如果您要构建新应用 xff0c 最好的选择
  • 使用docker-compose搭建Nextcloud个人云盘并开启https教程

    一 前言 之前一直采用LANMP直接搭建服务 xff0c 但后来使用docker后 xff0c 搭建和迁移数据都很方便 xff0c 所以将服务都容器化 下面介绍一下使用docker compose搭建Nextcloud xff0c 并且使用
  • Linux中如何查Jetson Nano中jetpack的版本

    命令 xff1a cat etc nv tegra release 如下图所示 xff0c 输入的内容为 R32 release REVISION 5 1 GCID 26202423 BOARD t210ref EABI aarch64 D
  • docker-compose.yml传入环境变量参数进容器,springboot使用。

    参考 xff1a https docs docker com compose compose file compose file v3 compose file v34 and under https docs docker com com
  • Docker Compose

    1 Docker Compose官网说明 理解 Compose是Docker官方的开源项目 需要安装 xff01 Dockerfile 让程序在任何地方运行 web服务 redis mysql nginx 多个容器 run Compose的
  • TX2(2): 安装JetPack L4T 3.1 (9003载板)

    参考官网教程 xff0c 其实官网教程已经挺详细 xff0c 主要看官网教程就行 http docs nvidia com jetpack l4t 3 1 index html developertools mobile jetpack l
  • docker、docker-compose和Portainer的安装

    一 docker安装 span class token comment 安装docker相关依赖 span yum span class token function install span y yum utils device mapp
  • Jetson tx2 安装jetpack_3.3手动安装cuda9.0,cudnn7.1

    1 刷机前的准备 xff08 写在前面的话 xff09 装有Ubuntu16 04或者Ubuntu18 04的电脑 xff0c 这里说的电脑可以是台式机也可以是笔记本与TX2区分开来 xff08 电脑是16 04或者18 04无所谓 xff
  • Jetpack练手(03):DataBinding

    文章目录 一 导入依赖二 搭建布局三 创建 ViewModel 数据对象四 修改布局为 DataBinding 布局五 绑定数据六 Demo 效果 一 导入依赖 新建 DataBindingDemo 工程 xff0c 参照 LiveData
  • Android DataBinding的基本使用

    5 DataBinding https developer android com topic libraries data binding custom conversions 数据绑定库是一种支持库 借助该库 您可以使用声明性格式 而非
  • jetpack Compose 学习笔记

    目录 Modifier clickable 取消点击水波纹 LazyColum 相关 Modifier clickable 取消点击水波纹 modifier Modifier clickable onClick indication nul
  • Jetpack学习之Room

    Android采用sqlite作为数据库存储 Room就是Google推出的自己的ORM Object Relational Mapping Room的架构图 Entity 一个Entity对应于数据库中的一张表 Entity类是Sqlit
  • Jetpack学习之Lifecycle

    Jetpack是Google为了解决Android架构问题而引入的 Google官方说的说法 Jetpack是一套库 工具和指南 可以帮助开发者更轻松地编写应用程序 Jetpack中的组件可以帮助开发者遵循最佳做法 摆脱编写样板代码的工作并
  • Github上 简单易用的 Android ViewModel Retrofit框架

    RequestViewModel 长期更新 支持网络请求的ViewMode框架 ViewModel LiveData Retrofit github 地址 https github com miaotaoii RequestViewMode
  • Navigation Preview unavailable in Android Studio 3.4 Preview

    Navigation Preview unavailable in Android Studio 3 4 Preview 最近在学Jetpack Navigation组件 但是在写navigation资源文件的时候 Preview 显示不出
  • LiveData详细分析2

    一 LiveData是什么东西 1 基于观察者设计模式 LiveData是一种持有可被观察数据的类 被观察者 LiveData需要一个观察者对象 一般是Observer类的具体实现 当观察者的生命周期处于STARTED或RESUMED状态时
  • Android Jetpack 之 DataStore

    1 概述 Google 推出了 JetPack 的新成员 DataStore DataStore 是一种新的数据存储方案 DataStore 以异步 一致的事务方式存储数据 克服了 SharedPreferences 的一些缺点 Jetpa
  • Jetpack学习之LiveData

    LiveData是一个可被观察的数据容器类 它是一个数据的容器 将数据包装起来 使数据成为被观察者 当该数据发生变化时 观察者能够获得通知 和ViewModel的关系 ViewModel用于存放页面所需的各种数据 以及数据相关的业务逻辑 因

随机推荐

  • wordpress插件API入口

    lt php 64 package Moodo Zhong 64 version 1 0 0 Plugin Name Moodo Zhong Plugin URI http wordpress org plugins hello dolly
  • PHP源码目录说明

    1 build 和编译有关的目录 2 ext 扩展库代码 xff0c 例如 MySQL zlib iconv 等我们熟悉的扩展库 其中 ext standard 目录下是常用的标准函数集 3 main 主目录包含主要的 PHP 宏和定义 4
  • 终端程序定义示例

    interrupt 0 外部中断0 interrupt 1 T0中断 interrupt 2 外部中断1 interrupt 3 T1中断 interrupt 4 串口中断 我来告诉你实质 xff1a 单片机的中断处理是这样工作的 xff0
  • lisp学习资料

    中文LISP学习网站 CL HTTP franz com 217条消息 使用hunchentoot搭建Lisp web 服务器 keyboardOTA的博客 CSDN博客
  • GO调用C语言之字符串传递

    C xff1a hello h include lt stdlib h gt include lt stdio h gt include lt string h gt char abc int strnum char str C hello
  • C++-基础语法-cin.getline() 与 cin.get() 的区别,以及getline()函数使用方法

    参考声明 xff1a C 43 43 primer plus https blog csdn net best fiends zxh article details 53064771 https blog csdn net u0114216
  • Kotlin开发中的一些Tips(二)

    接着上一篇 xff0c 最近又整理了一些 1 作用域函数选择 目前有let run with apply 和 also五个作用域函数 官方文档有张表来说明它们之间的区别 xff1a 总结一下有几点区别 xff1a apply和also返回上
  • Jetpack Compose 从入门到入门(一)

    Jetpack Compose 是用于构建原生 Android 界面的新工具包 它使用更少的代码 强大的工具和直观的 Kotlin API xff0c 可以帮助您简化并加快 Android 界面开发 xff0c 打造生动而精彩的应用 它可让
  • Jetpack Compose 从入门到入门(二)

    开始布局部分 这部分我个人感觉没有必要每个组件 属性都详细说到 xff0c 否则篇幅会很长 建立起Compose中的组件与 Android Views的一个对应关系就够了 具体还是需要在实际的使用中去熟悉 1 Column 子元素按竖直顺序
  • Jetpack Compose 从入门到入门(三)

    本篇开始介绍Jetpack Compose 中的修饰符Modifier 修饰符可以用来执行以下操作 xff1a 更改可组合项的大小 布局 行为和外观 添加信息 xff0c 如无障碍标签 处理用户输入 添加高级互动 xff0c 如使元素可点击
  • 【操作系统】Linux系统中直接优化提升CPU性能(已解决)

    文章目录 问题 xff1a 服务器CPU没有调用最高性能 xff0c 导致跑算法的时候处理速度慢一 BIOS方法二 终端直接设置CPU调节器方法1 查看当前CPU调节器2 安装各种依赖库3 最后安装cpufrequtis工具包并设置CPU调
  • Jetpack Compose 从入门到入门(四)

    本篇开始介绍Jetpack Compose 中常用的组件 有一部分之前的文章中也出现过 xff0c 今天详细说明一下 1 Text 日常最常用的应该就是显示文字 xff0c 所以有必要说一下Text控件 首先源码如下 xff1a span
  • Jetpack Compose 从入门到入门(五)

    应用中的状态是指可以随时间变化的任何值 这是一个非常宽泛的定义 xff0c 从 Room 数据库到类的变量 xff0c 全部涵盖在内 由于Compose是声明式UI xff0c 会根据状态变化来更新UI xff0c 因此状态的处理至关重要
  • Jetpack Compose 从入门到入门(六)

    本篇说说Compose中的Canvas 1 Canvas span class token annotation builtin 64 Composable span span class token keyword fun span sp
  • Jetpack Compose 从入门到入门(七)

    本篇进入Compose 动画部分 1 动画预览 在本系列第一篇中我们提到过 xff0c 64 Preview可以帮我们实现UI的预览功能 xff0c 简单的交互和播放动画 在Android Studio Bumblebee xff08 大黄
  • Android 12 变更及适配攻略

    这几个月有点忙 xff0c 一年一篇的适配文章来的有点晚了 但其实也还好 xff0c 因为我们项目也是下半年才适配 我这边也是提前调研踩坑 xff0c 评估一下工作量 这个时间点也完全跟得上Google Play的审核要求 xff08 11
  • Jetpack Compose 从入门到入门(八)

    接着上一篇的动画部分 xff0c 本篇主要是自定义动画与Animatable AnimationSpec 上一篇中 xff0c 出现了多次animationSpec属性 xff0c 它是用来自定义动画规范的 例如 xff1a span cl
  • Jetpack Compose 从入门到入门(九)

    本篇是Compose的手势部分 点击 添加clickable修饰符就可以轻松实现元素的点击 此外它还提供无障碍功能 xff0c 并在点按时显示水波纹效果 span class token annotation builtin 64 Comp
  • 记参加 2022 Google开发者大会

    前几天有幸参加了2022年Google 开发者大会 Google Developer Summit xff0c 上一次参加Google开发者大会还是2019年 这期间因为众所周知的原因 xff0c 开发者大会都改为了线上举办 和上次相比可以
  • Jetpack Compose 从入门到入门(十)

    本篇介绍如何将Jetpack Compose 添加到已有应用中 xff0c 毕竟大多数情况都是在现有项目中使用 Jetpack Compose 旨在配合既有的基于 View 的界面构造方式一起使用 如果您要构建新应用 xff0c 最好的选择