声明式UI是否会成为Android开发的主流?
从Windows到Web,到Android,到iOS,我们编写应用 (App) 最初的方式都是命令式的 (Imperative Style) 。但随着声明式 (Declarative Style) 的出现,情况正在发生极速的变化。我们先看看命令式和声明式分别怎么写UI。
命令式 vs 声明式
命令式 (Imperative Style)
命令式的方式是一种自然而然想到的方式,我们写代码构建整个UI (view tree),在需要更新UI时 (比如获取到网络数据后或者用户改变UI元素后) 从view tree里查找到对应的元素,再更新它。比如在Android开发中,我们通过findViewById查找到某文本元素,再给它设置显示的内容:
TextView tv = findViewById(R.id.text_view);
tv.setText("Hello World");
声明式 (Declarative Style)
命令式的方式是一种最朴素的方式,它要求我们针对每一次UI的变更都亲自写代码修改view tree,且这些代码分散在各个地方。那么我们有没有方法把我们从对view tree的频繁操作中解放出来呢?有。Facebook的React框架就是一个知名的先驱。声明式的方式集中在一个地方声明UI的结构,UI的变化通过数据来驱动。我们只需要修改数据,剩下的修改view tree的工作交给框架来做。
声明式发展历程
其实声明式的UI布局方式已经有比较长的历史,下面简单介绍一些比较知名的
Facebook React
前端开发在React之前,比较常用的是jQuery这种命令式的框架。下面是一个jQuery的例子,用ajax发起一个网络请求,请求返回结果后在DOM树里搜索到节点 ($("#weather-temp")) ,再将结果设置给节点显示出来。
$.ajax({url: "/api/getWeather",data: {zipcode: 97201},success: function( result ) {$("#weather-temp").html( "<strong>" + result + "</strong> degrees" );}
});
Facebook内部从2011年开始开发FaxJS,也就是React的原型,并于2013年开源了React。下面是一个React声明式UI的例子
class MarkdownEditor extends React.Component {constructor(props) {super(props);this.md = new Remarkable();this.handleChange = this.handleChange.bind(this);this.state = { value: 'Hello, **world**!' };}handleChange(e) {this.setState({ value: e.target.value });}getRawMarkup() {return { __html: this.md.render(this.state.value) };}render() {return (<div className="MarkdownEditor"><h3>Input</h3><label htmlFor="markdown-content">Enter some markdown</label><textareaid="markdown-content"onChange={this.handleChange}defaultValue={this.state.value}/><h3>Output</h3><divclassName="content"dangerouslySetInnerHTML={this.getRawMarkup()}/></div>);}
}root.render(<MarkdownEditor />);
渲染效果:
我们将某个Component的UI描述全部放在render方法里,这个Component有它自己的状态 (state)。当用户在textarea输入内容时,handleChange会被调用,它会从textarea取出当前值,赋给value这个state变量,调用setState方法告诉React框架需要更新UI,然后框架就会完成剩下的所有工作。对开发者来说非常的简单高效。
Facebook React Native
Facebook在2015年开源了React Native这个跨平台的框架,它可以让你通过前端技术栈开发Android和iOS应用。它声明UI的方式和React一模一样,如下所示
import React from 'react';
import {Text, View} from 'react-native';
import {Header} from './Header';
import {heading} from './Typography';const WelcomeScreen = () => (<View><Header title="Welcome to React Native"/><Text style={heading}>Step One</Text><Text>Edit App.js to change this screen and turn itinto your app.</Text><Text style={heading}>See Your Changes</Text><Text>Press Cmd + R inside the simulator to reloadyour app’s code.</Text><Text style={heading}>Debug</Text><Text>Press Cmd + M or Shake your device to open theReact Native Debug Menu.</Text><Text style={heading}>Learn</Text><Text>Read the docs to discover what to do next:</Text></View>
);
Facebook Litho
Facebook在2017年开源了Litho这个高性能的Android UI开发框架,在开源之前已在内部主要App广泛使用,如Facebook等。受React的影响,它也采用了声明式的UI布局方式。下面是一个例子
class PostStyledKComponent(val post: Post) : KComponent() {override fun ComponentScope.render(): Component {return Column {child(Row(alignItems = YogaAlign.CENTER, style = Style.padding(all = 8.dp)) {child(Image(drawable = drawableRes(post.user.avatarRes),style = Style.width(36.dp).height(36.dp).margin(start = 4.dp, end = 8.dp)))child(Text(text = post.user.username, textStyle = Typeface.BOLD))})child(Image(drawable = drawableRes(post.imageRes),scaleType = ImageView.ScaleType.CENTER_CROP,style = Style.aspectRatio(1f)))}}
}
渲染效果:
Google Flutter
Google在2018年发布了Flutter的第一个稳定版本v1.0.0。它采用了声明式的布局方式,下面是一个简单的例子
class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Welcome to Flutter',home: Scaffold(appBar: AppBar(title: const Text('Welcome to Flutter'),),body: const Center(child: Text('Hello World'),),),);}
}
Apple SwiftUI
Apple在2019年发布了SwiftUI的第一个版本,它让你用声明式的方式来写iOS应用。下面是一个简单的例子
import SwiftUIstruct AlbumDetail: View {var album: Albumvar body: some View {List(album.songs) { song in HStack {Image(album.cover)VStack(alignment: .leading) {Text(song.title)Text(song.artist.name).foregroundStyle(.secondary)}}}}
}
Google Jetpack Compose
Google在2021年7月发布了Jetpack Compose的第一个稳定版本v1.0,像Flutter一样采用声明式UI布局方式,但Compose的设计比Flutter更合理一些。在Flutter里,你要给一个Widget设置宽高等属性都需要在外面套一层Container来实现,这非常的臃肿,而其它声明式的框架,包括Compose,大都可以通过节点的属性来设置。下面是一个Compose的简单例子
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp@Composable
fun MessageCard(msg: Message) {// Add padding around our messageRow(modifier = Modifier.padding(all = 8.dp)) {Image(painter = painterResource(R.drawable.profile_picture),contentDescription = "Contact profile picture",modifier = Modifier// Set image size to 40 dp.size(40.dp)// Clip image to be shaped as a circle.clip(CircleShape))// Add a horizontal space between the image and the columnSpacer(modifier = Modifier.width(8.dp))Column {Text(text = msg.author)// Add a vertical space between the author and message textsSpacer(modifier = Modifier.height(4.dp))Text(text = msg.body)}}
}
渲染效果:
展望
我们看到2017年的Litho,2018年的Flutter,2019年的SwiftUI,2021年的Jetpack Compose都采用了声明式的UI布局方式,已呈燎原之势,声明式的UI布局方式未来会像前端领域的React一样成为主流吗?
声明式UI是否会成为Android开发的主流?相关推荐
- Android声明式UI框架 Litho 初探——基础使用
初衷 Litho作为一个高性能的UI引擎,学习曲线还是比较高的,但是在国内能用的资料非常少(大部分都是相互复制的"Hello Word"教程),国外除了Litho自己的文档外,也没 ...
- 声明式UI(Declarative)和命令式(Imperative)UI的差异?
声明式UI(Declarative)和命令式(Imperative)UI的差异? 声明式 这里应该展示一个缩小50%的,旋转180的图片.可以表示为,what should happen. 命令式 需 ...
- Android声明式UI框架-Litho-初探——基础使用篇
初衷 Litho作为一个高性能的UI引擎,学习曲线还是比较高的,但是在国内能用的资料非常少(大部分都是相互复制的"Hello Word"教程),国外除了Litho自己的文档外,也没 ...
- Android的 API 框架,Android 声明式 UI 框架 Litho 初探 —— Sections API
在最开始入门介绍中,我们曾经用SingleComponentSection完成了一个简单的列表,当时的做法是使用 for 构造出了多个子Component.其实在 Litho 中提供了一个性能更好的方 ...
- 告别XML,Android新声明式UI框架《Jetpack Compose入门到精通》最全开发指南
什么是Jetpack Compose? Jetpack Compose是Android的新声明式UI框架.长期以来, Android 开发人员习惯于使用带有状态视图的xml编写UI,这些状态视图通过逐 ...
- 2017-05-04-Facebook出品的Android声明式开源新框架Litho文档翻译-总览和导航
本文是博主转发自己的博客文章至CSDN. 欢迎点击博主的博客查看原文,体验更好的浏览感受. 欢迎转载,转载请标明出处. 今天逛github发现facebook开源了一个新框架Litho,大概看了一下介 ...
- Jetpack Compose--声明式UI替代传统命令式UI的新产品
Jetpack Compose--声明式UI替代传统命令式UI的新产品 声明式UI与传统UI创建方式(命令式UI)的区别 Jetpack Compose的优势 Jetpack Compose的缺点 最 ...
- 为什么说 Compose 的声明式代码最简洁 ?Compose/React/Flutter/SwiftUI 语法对比
前言 Comopse 与 React.Flutter.SwiftUI 同属声明式 UI 框架,有着相同的设计理念和相似的实现原理,但是 Compose 的 API 设计要更加简洁.本文就这几个框架在代 ...
- 阿里Android开发规范:安全与其他
以下内容摘自 阿里巴巴Android开发手册 我们的目标是: 防患未然,提升质量意识,降低故障率和维护成本: 标准统一,提升协作效率: 追求卓越的工匠精神,打磨精品代码. [强制]必须遵守,违反本约定 ...
最新文章
- 如何在指定文件夹下进入jupyter notebook
- fancybox 在打开窗口前 先执行 js脚本,fancybox设置只能通过右上角关闭,fancybox遮罩层关闭...
- jQuery里面的addClass讲解
- scale html 浏览器,javascript中scale怎么使用?
- 北邮计算机学不学单片机,北邮小学期PC单片机.docx
- 戴帽子对眼睛是否有好处
- 到无限(溪流)和超越!
- .NET下实现分布式缓存系统Memcached
- 如何合理地决定线程池大小?
- 麦迪逊大学计算机科学咋样,威斯康星大学麦迪逊分校计算机专业排名
- 利用Easy-Rules实现动态业务规则
- Javascript中的执行环境及作用域
- python numpy安装失败_【Python】pip安装numpy安装到一半失败解决办法
- 500强企业专家级面试果然是噩梦级,吐血分享成功经验
- 三阶魔方层先还原方法图解
- 网络直播算是计算机技术吗,计算机网络技术与电视直播新闻的融合发展
- 【继承系列】JS中的组合继承
- 智能制造系统架构和标准体系结构
- 以太网工业RFID读写器|读卡器CK-FR12-E01接线说明与PLC组网方案
- 最高要价 8888元,小米 11 邀请函现身闲鱼;马斯克曾考虑把特斯拉卖给苹果却被拒;我国区块链专利全球居首 | EA周报...
热门文章
- 【运行报错】Redis:Operation against a key holding the wrong kind of value
- R语言︱贝叶斯网络语言实现及与朴素贝叶斯区别(笔记)
- 网址被QQ拦截后应该怎么做才可能尽快解除拦截
- 作为反馈电路有很好的相位裕度、但很差的稳定性能的一个例子
- iOS中mmap的应用
- Springboot整合Elasticsearch 报错availableProcessors is already set to [4], rejecting [4]
- Java命令简易入门-2:javac与java命令之一(javac)
- [人体运动分析]关节中心的计算
- 数据结构-火车车厢重排问题(队列实现)
- 当游戏爱上MongoDB–参会赢Kindle