Android全新UI框架之Jetpack Compose入门基础

news2024/12/23 13:16:03
  • Jetpack Compose是什么
    如果有跨端开发经验的同学,理解和学习compose可能没有那么大的压力。简单地说,compose可以让Android的原生开发也可以使用类似rn的jsx的语法来开发UI界面。以往,我们开发Android原生页面的时候,通常是在xml中画相关的UI控件,然后在activity中通过findViewById拿到相关的控件对象,接着根据业务需求调用该控件对象的相关API方法。这种方式官方称之为命令式UI。再加上大前端浪潮的兴起,React、Vue等声明式UI技术的的日益成熟,以往那套继承自View的组件体系已经越发难以维护(目前View.java已超过3万行代码),因此Compose这门技术就应运而生了。

  • Jetpack Compose的优势
    这点感兴趣的同学就到官网看下就行了,反正就是一堆好处。值得注意的是compose最低兼容到API21

  • Compose API设计原则
    由于Compose在编程范式上与传统视图体系有着根本的不同,在开始深入学习Compose之前,有必要对Compose API的设计原则做一个介绍。无论是Compose预置的Composable还是开发者自己定义的Composable,都应该遵守这些原则

    1. 一切皆为函数
      Compose声明式UI的基础是Composable函数Composable函数通过多级嵌套形成结构化的函数调用链,函数调用链经过运行后生成一颗UI视图树。视图树一旦生成便不可随意改变。视图的刷新依靠Composable函数的反复执行(重组)来实现。当需要显示的数据发生变化时,Compoable基于新参数再次执行,更新底层的视图树,最终完成视图的刷新。
      在这里插入图片描述
      Composable函数只能在Composable函数中调用,这与挂起函数只能在协程或其他挂起函数中调用类似,都是在编译期保证的。在Compose的世界中,一切组件都是函数,由于没有类的概念,因此不会有任何继承的层次结构,所有组件都是顶层函数,可以在DSL中直接调用。
    2. 组合优于继承
      Composable作为函数相互没有继承关系,这有利于促使开发者使用组合的视角去思考问题。
    3. 单一数据源
      在传统的命令行UI中(以EditText为例),文字的变化来源多处,有可能来自用户的输入,也可能来自代码某处的setText。状态变化可能不止一个来源,即所谓的多数据源。多数据源下的状态变化不容易跟踪,且会使后期难以维护。单一数据源决定了Composable数据流的单向流动,数据(name)总是自上而下(由父组件流向子组件)流动,而事件(onNameChange)总是自下而上(由子组件流向父组件)传递。
  • Compose与View的关系
    在传统视图体系中由View与ViewGroup构成视图树,而Compose中也有同样一颗视图树,它由LayoutNode构成,由Composition负责管理。
    在这里插入图片描述
    两种树的节点类型不同,但是它们并非全没关系,依然可以共存于一棵树中。就像DOM节点与View也不同,但是可以通过WebView显示在一棵树上,Compose也可以借助这样一个连接点挂载在View树上。使用Android Studio自带的Layout Inspector可以看到这个连接点就是ComposeView,它就是连接View与Compose的桥梁。
    在这里插入图片描述
    ComposeView有一个唯一子节点AndroidComposeView,它既是一个ViewGroup,也是LayoutNode视图树的持有者,它实现了LayoutNode视图结构与View视图结构的连接。既然AndroidComposeView已经承担了两套体系的连接,那为什么还要多一层ComposeView呢?
    ComposeView继承自AbstractComposeView,而后者有三个子类,分别对应着Activity窗口、Dialog窗口与PopupWindow窗口。Android平台存在所谓Window的概念,我们在很多场景下会有多窗口需求,例如在页面中弹出一个对话窗。AbstractComposeView的子类负责Android平台各类窗口的适配并生成对应的Composition, ComposeView作为其中一个子类负责Activity窗口的适配。总体来说,ComposeView负责对Android平台的Activity窗口的适配,AndroidComposeView负责连接LayoutNode视图系统与View视图系统。如此的职责划分可以实现上层视图适配与下层窗口适配逻辑的解耦。

Composition是视图树的创建者。从Composable函数到视图树的生成经历这个过程:
第一步Composable函数执行后填充SlotTable, SlotTable中记录着Composable执行过程的状态信息;
第二步基于SlotTable生成和更新LayoutNode视图树。Composition负责从Composable执行到视图树生成(更新)的整个过程。

ComposeView接入View视图后,内部的UI工作都在Compose侧闭环处理,来自AndroidComposeView的绘制、测量布局与手势事件分发等都下沉到LayoutNode去完成。ComposeView作为View可以挂载到原有View视图树中的任意位置。因此一个传统视图项目可以通过ComposeView阶段性地接入Compose。一个纯Compose页面就是将ComposeView直接挂载到ContentView上面。

  • 不只是Android UI框架
    Compose还包含一些其他的库,如下图所示:
    在这里插入图片描述
    Compose从上到下分为四层,每一层都可以被单独使用,在不同维度提供能力支持。可以只使用Compose的Runtime层构建任何基于数据驱动能力的系统或类库。在这样清晰的分层结构下,我们甚至可以隔离那些平台相关代码,自底向上自己来实现跨平台的UI系统。
    在这里插入图片描述
  • Compose开发环境搭建
    1. 创建一个新的Compose项目
      这个比较简单,使用AndroidStudio创建项目时,选择compose项目,然后无脑下一步即可,如下图所示:
      在这里插入图片描述
    2. 已有项目引入Compose
      按照下面步骤改造已有项目:
      • 在工程中引入Compose相关依赖:
        dependencies {
            implementation platform('androidx.compose:compose-bom:2022.10.00')
            implementation 'androidx.compose.ui:ui'
            implementation 'androidx.compose.material3:material3'
        }
        
      • 在build.gradle文件的android闭包中添加如何下配置:
            buildFeatures {
                compose true
            }
            composeOptions {
                kotlinCompilerExtensionVersion '1.3.2'
            }
            packagingOptions {
                resources {
                    excludes += '/META-INF/{AL2.0,LGPL2.1}'
                }
            }
        
      • 修改相关的xml布局文件
        <?xml version="1.0" encoding="utf-8"?>
        <androidx.compose.ui.platform.ComposeView 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:id="@+id/root"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
        
        </androidx.compose.ui.platform.ComposeView>
        
      • 在activity中查找该View并使用setContent即可
        class MainActivity : AppCompatActivity() {
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_main)
                findViewById<ComposeView>(R.id.root).setContent { 
                    Text(text = "Hello Compose")
                }
            }
        }
        
    3. 在Compose中使用View组件
      不少功能性的传统视图控件在Compose中没有对应的Composable实现,例如SurfaceView、WebView、MapView等。因此在Compose中可能会有使用传统View控件的需求。Compose提供了名为AndroidView的Composable组件,允许在Composable中插入任意基于继承自View的传统视图控件。
      class MainActivity : ComponentActivity() {
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContent {
                  AndroidView(factory = { context ->
                      WebView(context).apply {
                          settings.javaScriptEnabled = true
                          webViewClient = WebViewClient()
                          loadUrl("https://www.baidu.com/")
                      }
                  }, modifier = Modifier.fillMaxSize())
              }
          }
      }
      

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

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

相关文章

【八股文面试】Java基础常见面试题总结(上)

Java基础常见面试题总结(上) Java有哪些特性 简单易学&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b;支持多线程&#xff08; C 语言没有内置的多…

Springcloud:LiteFlow

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、LiteFlow简介 二、规则编排关键字及语法 1、THEN&#xff1a; 2、WHEN&#xff1a; 3、AND&#xff1a; 4、OR&#xff1a; 5、IF&#xff1a; 6、ELSE&…

手动代码实现神经网络

网络结构 第一层有13个神经元&#xff0c;第二层8个神经元&#xff0c;第三层是输出层&#xff1b;其中第一层的激活函数是relu&#xff0c;第二层是sigmoid 代码实现 # 导入库 import torch import torch.nn as nn from torch.nn import functional as F # 确定数据 torch…

使用IntelliJ IDEA查看接口的全部实现方法

在大型Java项目中&#xff0c;经常会使用接口和抽象类进行代码设计。为了更好地了解代码结构和功能&#xff0c;我们需要快速查看一个接口的所有实现类。IntelliJ IDEA提供了一些方便的方法来实现这一目标。 1. 点击查看接口的实现子类 在IDEA中&#xff0c;你可以轻松地查看…

swagger 内容信息与代码不一致,已解决

ApiModel是Swagger中的常用到的注解&#xff0c;检查下信息错误的实体类的ApiModel的value值是否一致&#xff0c;应该是写错了&#xff0c;是不是张冠李戴了

STM32 TIM2重映射

STM32定时器 文章目录 STM32定时器[TOC](文章目录) 前言一、问题分析二、代码 前言 最近想弄一个多路输出PWM&#xff0c;但是发现TIM2不能用&#xff0c;根据手册也对它进行重映射了&#xff0c;但是还是不能用&#xff0c;用示波器发现驱动能力比较弱&#xff0c;然后禁用jt…

博途PLC PID仿真(单容水箱液位高度控制)

单容水箱和双荣水箱的微分方程和数值求解,可以参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/131139432https://rxxw-control.blog.csdn.net/article/details/131139432这篇博客我们利用欧拉求解器在PLC里完成单容水箱的数学建模。PLC也可以和MATL…

【笔记】【算法设计与分析 - 北航童咏昕教授】绪论

算法设计与分析 - 北航童咏昕教授 文章目录 算法的定义定义性质 算法的表示自然语言编程语言伪代码 算法的分析算法分析的原则渐近分析 算法的定义 定义 给定计算问题&#xff0c;算法是一系列良定义的计算步骤&#xff0c;逐一执行计算步骤即可得预期的输出。 性质 有穷性确…

运维07:堡垒机

什么是跳板机 跳板机就是一台服务器而已&#xff0c;运维人员在使用管理服务器的时候&#xff0c;必须先连接上跳板机&#xff0c;然后才能去操控内网中的服务器&#xff0c;才能登录到目标设备上进行维护和操作 开发小张 ---> 登录跳板机 ---> 再登录开发服务器 测试…

vue3 用xlsx 解决 excel 低版本office无法打开问题

需求背景解决思路解决效果将json导出为excel将table导为excel导出样式 需求背景 原使用 vue3-json-excel &#xff0c;导致在笔记本office环境下&#xff0c;出现兼容性问题 <vue3-json-excel class"export-btn" :fetch"excelGetList" :fields"js…

Aster实现一台电脑当两台使——副屏搭配键鼠

前言&#xff1a;笔者每年回家&#xff0c;都面临着想要和小伙伴一起玩游戏&#xff0c;但小伙伴没有电脑/只有低配电脑的问题。与此同时&#xff0c;笔者自身的电脑是高配置的电脑&#xff0c;因此笔者想到&#xff0c;能否在自己的电脑上运行游戏&#xff0c;在小伙伴的电脑上…

Code-Audit(代码审计)习题记录

介绍&#xff1a; 自己懒得搭建靶场了&#xff0c;靶场地址是 GitHub - CHYbeta/Code-Audit-Challenges: Code-Audit-Challenges为了方便在公网练习&#xff0c;可以随地访问&#xff0c;本文所有的题目均来源于网站HSCSEC-Code Audit 1、习题一 题目内容如下&#xff1a; 1…

2024pytest自动化测试框架学习(三)

在自动化测试中我们经常会针对某些测试方法编写前置测试数据&#xff0c;当测试方法执行完毕后再清理这些测试数据。之前我们接触的unittest框架中&#xff0c;使用setUp、tearDown方法来解决前置数据、后置数据销毁的问题。pytest为我们提供了更加强大灵活的fixtrue来完成该实…

《Solidity 简易速速上手小册》第8章:高级 Solidity 概念(2024 最新版)

文章目录 8.1 高级数据类型和结构8.1.1 基础知识解析更深入的理解实际操作技巧 8.1.2 重点案例&#xff1a;构建一个去中心化身份系统案例 Demo&#xff1a;创建去中心化身份系统案例代码DecentralizedIdentityContract.sol 测试和验证拓展案例 8.1.3 拓展案例 1&#xff1a;管…

MedicalGPT 训练医疗大模型,实现了包括增量预训练、有监督微调、RLHF(奖励建模、强化学习训练)和DPO(直接偏好优化)

MedicalGPT 训练医疗大模型&#xff0c;实现了包括增量预训练、有监督微调、RLHF(奖励建模、强化学习训练)和DPO(直接偏好优化)。 MedicalGPT: Training Your Own Medical GPT Model with ChatGPT Training Pipeline. 训练医疗大模型&#xff0c;实现了包括增量预训练、有监督微…

我为什么不喜欢关电脑?

程序员为什么不喜欢关电脑&#xff1f; 你是否注意到&#xff0c;程序员们似乎从不关电脑&#xff1f;别以为他们是电脑上瘾&#xff0c;实则是有他们自己的原因&#xff01;让我们一起揭秘背后的原因&#xff0c;看看程序员们真正的“英雄”本色&#xff01; 一、上大学时。 …

AP5216 降压恒流 全亮 半亮9W 车灯手电筒 性价比方案

AP5216 是一款 PWM工作模式, 高效率、外 围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高 精度降压 LED 恒流驱动芯片。输出功率可达 9W&#xff0c;电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过 MODE 切换&#xff1a;全亮/半亮 模式。AP5216…

《小程序商城定制:为你打造独特的线上商业帝国》

在当今数字化的时代&#xff0c;拥有一个定制的小程序商城已经成为了许多企业和个人创业者的首要任务。小程序商城作为一种轻量级的移动应用&#xff0c;具有无需下载、使用方便、传播迅速等优势&#xff0c;为用户提供了更加便捷的购物体验。而通过定制小程序商城&#xff0c;…

linux部署jenkins,支持jdk1.8

无废话&#xff0c;纯干活安装指令 本文前提条件需安装jdk8&#xff0c;安装参考&#xff1a;Linux配置jdk环境 下载资源 # 创建安装目录 mkdir -p /data/jenkins && cd /data/jenkins# 下载jenkins的war包&#xff0c;v2.346.x支持jdk1.8&#xff0c;高于这个版本的…

书生·浦语大模型实战营第四节课作业

基础作业 fintune过程 这里要注意下。 合并完参数的模型再进行网页部署时&#xff0c;需要用到InternLM源码&#xff0c;教程里面忽略了需要commit版本。通过以下命令转到所需版本&#xff0c;然后就可以看到web_demo.py。 cd InternLM git checkout 3028f07cb79e5b1d7342f4…