从0开始搭建一个APP:compose搬砖的一天

news2024/11/25 18:52:17

无论是从各个大佬的书籍还是blog,大的方向还是翻了一遍,个人感觉,compose 是UI解决方案这种定义和Android离得特别远,像Android 的应用端的大多数工作量还是在UI开发上,flutter 也差不多,结合Kotlin的开发经验,我觉得compose 其实在Android上他可以理解成提供了特别多Kotlin作用域函数的自定义view,这一点,在今天的搬砖中感受得特别明显。当我们没法对UI行为进行抽象的时候,就感觉他不落地。

往常,Android中写一个界面,存在着各个细分领域,但是compose就不一样了,他啥都有,但是全靠想象力,就是写代码都时候,得有人一直说,格局得打开,想象力得打开。你得自己组装,而且知道自己组装的每一步是干什么,下一步得干什么,而之前的Android view的写法就不是这个样子,之前是最终汇总成一个结果,而compose走一步变一步,这就要求,我们对自定义view或者说对大多数view的绘制步骤了解得特别清晰。

今天和一个大佬唠嗑,说1天看完一本书,第二天就可以上手干,说自定义view强的话就可以,大佬觉得自己第2天就真的可以上手干了,emmmm,本身没有多少问题,就是有点打手。

个人觉得,compose 从Android 进阶的角度上来说,是可以学习使用的,他这种基于状态的刷新机制,特别像viewbinding 或者像 Html 通过数据生成dev 的那种感觉,而且是进阶版本,通过对比学习,肯定是可以更好的掌握UI的绘制的,而且现在各种自定义系统,神仙打架,真的需要将技能概念抽离出来,方便后期学习搬砖。

正文

okokok,水了这么多字,还是写正文。

Text 如何相对居中?

业务场景是,界面顶部有一个标题栏,而且标题栏上面就一个文本。那么换成Android view的写法估计就是:

<TextView
    android:textSize="16sp"
    android:gravity="center"
    android:text="标题"
    android:layout_width="match_parent"
    android:layout_height="44dp"/>

但是compose 的:

Text(text = "标题", modifier = Modifier.fillMaxWidth().height(44.dp).align(Alignment.Center))

就会发现,align这个函数导入不了包,哈?这不科学。

可以看到,这个属性,只有在box,column,row中有,okoko,所以,这种得这么写:

Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth().height(44.dp)){
    Text(text = "标题")
}

下面是效果:

compose 没有margin,只有padding

有这个想法的原因是,一个习惯,其实官方并不建议我们用margin去做view的间距,因为我们view的计算宽高和布置位置的时候,要计算margin 和padding的啊,官方建议我们用:

<Space
    android:layout_width="wrap_content"
    android:layout_height="10dp"/>

这个调调做view的间距,而在compose 中体现的极其明显,他直接把margin 给干没了,而compose 中也提供了Space,那就是:

Spacer(modifier = Modifier.height(10.dp))

所以,个人感觉,有些人说用padding,感觉一条路走到黑了。

要分割线还是用canvas自己画?

因为是做设置类型的界面。这种界面,都知道,喜欢画一根分割线,Android view 里面,做分隔线还不简单:

  • 可以是view 设置背景
  • 可是LinearLayoutCompat 设置divider。
  • 可以是recycleview 设置分割线。
  • viewGroup 的组合里面,我们为了体现技术(装B),也会用canvas 自己画一根直线。

实现方式多种多样,但是在compose 搬砖的第一天,这个玩意,怎么有点不丝滑?我好像没有记起来有这个调调,但是也不复杂,毕竟,我可以自己画一根不就可以了吗?compose 不提供不也正常吗,是吧。

Canvas(modifier = Modifier.fillMaxWidth().height(1.dp), onDraw = {
    drawRect(Color.Red)
})

emmm?可惜这个函数里面没有画RGB 纯颜色的,只要高度足够小,纯颜色,也可以是分割线,是吧。当我把这个写完的时候,突然想起,Android 里面并没有分割线的定义,都是叫divider:

Divider()

这个3个入参:

  • modifier 控制宽高,相对位置等杂七杂八的。
  • thickness 分割线的高度
  • color 分割线的颜色。

我们再来看看divider的源码:

@Composable
fun Divider(
    modifier: Modifier = Modifier,
    thickness: Dp = DividerDefaults.Thickness,
    color: Color = DividerDefaults.color,
) {
    val targetThickness = if (thickness == Dp.Hairline) {
        (1f / LocalDensity.current.density).dp
    } else {
        thickness
    }
    Box(
        modifier
            .fillMaxWidth()
            .height(targetThickness)
            .background(color = color)
    )
}

他自己整了一个box,设置了一个背景,分割线的高度就是box的高度,emmmmm?果真朴实无华,挺后悔自己想的怎么多,每天上一当,当当不一样。

要state 还是liveData?

compose 是基于state更新UI的,而我们MVVM通常建议我们使用LiveData,liveData的优点蛮多的,最起码的是不会出现生命周期问题,那么这两个能不能兼容呢?当然是可以了。 我们先来看一个通过viewModel 获取参数的例子。

class ComposeDebugViewModel:BaseViewModel(){
    var debugStare= mutableStateOf("name")
}

@Preview(showBackground = true)
@Composable
fun debugPage(){
    var name by remember {
        viewModel.debugStare
    }
    Text(text = name, modifier = Modifier.clickable {
        name="${System.currentTimeMillis()}"
    })
}

功能很简单,每次点击text,就将text 上的文本刷新为 点击时候的时间戳,但是就会发现,预览不了,这就涉及到一个名称,叫状态提升了,我们将点击事件和指,通过外部传入进来,并且是设置默认值,就可以预览了。

    @Composable
    override fun pageContent() {
        var name by remember {
            viewModel.debugStare
        }
        debugPage(name){
            name="${System.currentTimeMillis()}"
        }
    }
    @Preview(showBackground = true, showSystemUi = true)
    @Composable
    fun debugPage(name:String="测试数据",clickable:()->Unit={}){
        Text(text = name, modifier = Modifier.clickable {
            clickable
        })
    }

class ComposeDebugViewModel:BaseViewModel(){
    var debugStare= mutableStateOf("name")
}

这么一改,我们就将预览和正式的UI通过数据拆解出来了。但是呢,我们还是没有用到LiveData.

为了全都要,我们需要导入一个maven,不就是导入个一个maven吗?

implementation("androidx.compose.runtime:runtime-livedata:1.5.4")

runtime 的?我们Kotlin导入到runtime 的包还少吗? 我们将上面的代码再次改造一下。

    @Composable
    override fun pageContent() {
        val name by viewModel.debugStare.observeAsState("默认值")
        debugPage(name){
            viewModel.debugStare.value="${System.currentTimeMillis()}"
        }
    }
    @Preview(showBackground = true, showSystemUi = true)
    @Composable
    fun debugPage(name:String="测试数据",clickable:()->Unit={}){
        Text(text = name, modifier = Modifier.clickable {
            clickable
        })
    }

class ComposeDebugViewModel:BaseViewModel(){
    var debugStare= MutableLiveData("name")
}

主要的改动点还是通过observeAsState 函数将LiveData转化成了state,同时name 的更新就得用LiveData进行更新了。这个就是compose上的单向数据流的概念,有一个经典的MVI的图,说对就是那个调调,具体实现上,最简单的就是这种。

因为Livedata的可以转换为state,这也是不没有用Flow的原因,嗯,感觉简单的接口请求LiveData 可能更好。

总结

OK,先水到这,主要是阐述了一些第一次开发可能遇到的简单问题,也没有啥知识点,水一下,也挺好。再提一嘴,compose和Kotlin的学习是差不多的,要把格局打开,就是想象力得打开,打开了就会发现,很多东西,他其实已经存在了。

Android 学习笔录

Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

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

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

相关文章

统计学习方法 逻辑斯蒂回归与最大熵模型

文章目录 统计学习方法 逻辑斯蒂回归与最大熵模型逻辑斯蒂回归逻辑斯蒂分布二项逻辑斯蒂回归多项逻辑斯蒂回归 最大熵模型原理定义学习极大似然估计 统计学习方法 逻辑斯蒂回归与最大熵模型 学习李航的《统计学习方法》时&#xff0c;关于逻辑斯蒂回归与最大熵模型的笔记。 逻…

【1】2023版密评算分工具

0X01 前言 工具根据商用密码应用安全性评估量化评估规则&#xff08;2023年8月1日实施&#xff09;实现 0x02 工具功能介绍 给定D A K的打分结果&#xff0c;计算单个测评对象和测评单元得分。根据测评单元得分计算测评层面得分根据测评层面得分计算报告整体得分配置文件说明…

美国亚马逊站暖手宝、热袜子、加热器UL499安全审核测试

近很多客户过来咨询&#xff0c;亚马逊上有人投诉产品起火&#xff0c;亚马逊要求提供UL报告&#xff0c;怎么办?特别是电池产品&#xff0c;很多卖家不约而同的提出同样的问题。不要着急&#xff0c;我司已经处理过很多类似产品&#xff0c;为很多商家提供了相应的报告&#…

【每日OJ题 —— 876. 链表的中间结点(链表)】

每日OJ题 —— 876. 链表的中间结点&#xff08;链表&#xff09; 1.题目&#xff1a; 876. 链表的中间结点2.方法讲解2.1.解法2.1.1.图文解析2.1.2.代码实现2.1.3.提交结果展示 1.题目&#xff1a; 876. 链表的中间结点 2.方法讲解 2.1.解法 2.1.1.图文解析 题解思路&#x…

ks ios快手极速版、概念版、创作版sig sig3

风控&#xff1a; 快手除了正版下&#xff0c;还有极速版&#xff0c;概念版&#xff0c;创作版。 然而看了下概念版还是风控比正版要低的多~ 抓包&#xff1a; 对于快手的ios版本抓包很简单&#xff0c;直接vpn转发抓包方式即可&#xff0c;不可用代理抓包&#xff1b;这个…

一款优秀的低代码平台应具备哪些能力?

低代码开发平台是一种基于低代码概念而研发出来的产品&#xff0c;是指无代码或少量代码就可以快速生成应用程序的平台。这类平台通过拼装可重复使用的组件&#xff0c;使开发人员可以通过可视化的工作界面快速设计应用&#xff0c;以解决传统软件开发模式周期长、成本高的问题…

LVGL库入门 04 - 颜色与图像

1、颜色 1.1、构造颜色 在 LVGL 中&#xff0c;颜色以结构 lv_color_t 表示。在最开始移植整个工程时&#xff0c;曾经在 lv_conf.h 中修改过颜色深度&#xff1a; /*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ #define LV_COLOR_DEPTH …

使用 javascript 在 n*m 网格中演示 BFS 广度优先搜索算法在带权重图中求最短路径

普通的广度优先最短路径搜索算法只能解决无权重的图&#xff1a; 求出的最短路径没问题&#xff0c;但是如果上边的空缺格子的距离为100呢&#xff1f;这种方式搜出的最短路径可能就是错的&#xff1a; 我们可以找一个距离1作为基本距离&#xff0c;然后距离为100的格子在搜索时…

[免费] 适用于 Windows的10 的十大数据恢复软件

Windows 10是微软开发的跨平台和设备应用程序的操作系统。它启动速度更快&#xff0c;具有熟悉且扩展的“开始”菜单&#xff0c;甚至可以在多种设备上以新的方式工作。所以&#xff0c;Windows 10非常流行&#xff0c;我们用它来保存我们的照片、音乐、文档和更多文件。但有时…

高效剪辑:视频剪辑新手如何批量分割视频

随着社交媒体和自媒体的兴起&#xff0c;视频剪辑已经成为一项必备的技能。无论是制作自己的电影、视频博客&#xff0c;还是为广告宣传提供支持&#xff0c;高效地剪辑视频都是非常重要的。对于视频剪辑新手来说&#xff0c;了解如何批量分割视频是提高剪辑效率的关键。本文讲…

左右联动 provide、inject+props、emit

实现效果 成都大屏 —— 视频管理 左右两个都是组件&#xff0c;所以涉及到父组件向多个子组建传递数据 方法1 provide、inject 目录结构 父组件 index.vue 用provide传递数据和修改数据的方法 import { provide} from "vue"; provide("Provide_Selected…

C语言队列实现

1.知识百科 队列是一种特殊的线性表&#xff0c;特殊之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作&#xff0c;和栈一样&#xff0c;队列是一种操作受限制的线性表。进行插入操作的…

月入8K, 计算机专业应届女孩转行5G网络优化工程师,她说:这行请慎入

小C说&#xff0c;如果要用两个字描述23年计算机专业的就业心情&#xff0c;那就是“焦虑”&#xff1b;用三个字描述23年计算机专业的就业环境&#xff0c;那就是“卷麻了”。 得益于张雪峰老师的就业推荐计算机专业需求的日益减少&#xff0c;2023年&#xff0c;计算机专业成…

【漏洞复现】74cms任意文件读取

漏洞描述 74CMS 是一款国内用的比较多招聘网站管理系统&#xff08;Job Board CMS&#xff09;&#xff0c;专注于招聘和人力资源领域的网站建设&#xff0c;存在任意文件读取漏洞 免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&#xff0c…

vue3中使用deck.gl

deck,gl网址&#xff1a;Home | deck.gl 因为deck.gl是国外的技术&#xff0c;国外最流行的框架是react&#xff0c;所以deck.gl有为react提供的地图组件&#xff0c;没有为vue提供&#xff0c;并且还需要翻墙。所以想用vue使用这个还是有一定难度的。 除了用到deck.gl之外还…

使用Serv-U FTP服务器共享文件,实现无公网IP的外网访问

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 科技日益发展的今天&#xff0c;移动电子设备似乎成了我们生活的主角&#xff0c;智能…

vue项目打包时按一定的名称规范生成对应的压缩包

在项目部署中经常需要将打包的dist按一定的名称压缩成压缩包&#xff0c;今天记录一下打包时生成压缩包的过程。其中有用到的npm包需要自己安装一下。 js文件放置的目录如下 compress.js内容如下&#xff1a; // compress.jsimport fs from "fs"; import shell fro…

电商价格数据监测接口|淘宝商品价格接口|天猫商品价格接口|京东商品价格接口|拼多多商品价格接口|API接口申请指南

电商价格数据监测接口是一种可以实时监测电商平台上商品价格的接口工具。通过这个接口&#xff0c;可以获取到各个电商平台的商品价格信息&#xff0c;并且可以设置价格监控频率、智能数据绑定、破价提醒机制等功能。 以下是电商价格数据监测接口的一些特点&#xff1a; 商城…

“恒山光量子”首秀!玻色量子联合移动云发表物理1区Top期刊SCPMA论文

2023年5月&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;联合移动云在我国知名科技期刊平台《中国科学&#xff1a;物理学 力学 天文学》英文版上发表了以“Optical experimental solution for the multiway number partitioning problem …

网络工程师进阶课:华为HCIP认证课程介绍

微思网络HCIP VIP试听课程&#xff1a;DHCP协议原理与配置https://www.bilibili.com/video/BV1cy4y1J7yg/?spm_id_from333.999.0.0 【微|信|公|众|号&#xff1a;厦门微思网络】 【微思网络http://www.xmws.cn&#xff0c;成立于2002年&#xff0c;专业培训21年&#xff0c;思…