声明式ui

Declarative UI is not a new concept in the development world, but it’s lately gaining momentum on mobile native SDK, probably after a few other cross-platform frameworks started exploring these approaches. Learning how to use them implies changing the way we imagined layouts, and overall graphical user interfaces, for the past years.

声明式UI在开发领域并不是一个新概念,但在移动本机SDK上,它已逐渐获得发展势头,这可能是在其他一些跨平台框架开始探索这些方法之后。 学习如何使用它们意味着在过去的几年中改变了我们对布局以及整体图形用户界面的想象方式。

As SwiftUI approaches on iOS, Jetpack Compose is being built in the open for the Android ecosystem.

随着SwiftUI在iOS上的发展,Jetpack Compose正在针对Android生态系统公开构建。

At the time of writing, Jetpack Compose is still being heavily developed, and many things change by the day.

在撰写本文时, Jetpack Compose仍在大力开发中,并且许多事情每天都在变化。

I wanted to give Compose a try and use it to create a small app that, given the Lego set number, will retrieve the basic information of such a kit: a picture, the title, and the link to the instructions.

我想尝试一下Compose并使用它来创建一个小型应用程序,给定Lego设置的编号,它将检索该工具包的基本信息:图片,标题和说明链接。

功能概述 (Overview of the functionalities)

As a developer, it’s pretty easy to highlight the main points in the aforementioned example:

作为开发人员,在上述示例中突出要点很容易:

  • A network request is needed to fetch the data from the web

    需要网络请求才能从Web上获取数据

  • The backend will most probably return a link to the image so that it has to be downloaded later

    后端很可能会返回指向该图像的链接,以便稍后必须下载

  • Data should be displayed on a list

    数据应显示在列表上

在舒适区内 (Inside the comfort zone)

Being familiar with the Android ecosystem, I pointed myself in the direction of using a whole bunch of well-known libraries to help me get the job done, and those include RecyclerView, Retrofit, KotlinX Serialization, Picasso, and Dagger.

熟悉Android生态系统后,我向自己指出了使用一堆知名库来帮助我完成工作的方向,这些库包括RecyclerView , Retrofit , KotlinX序列化 , Picasso和Dagger 。

The use of a dependency injection framework such as Dagger might seem overkill for such a small app, but in a real project, it should be the go-to for building your objects. In this case, using such an articulate framework that involves the use of kapt could cause a conflict with the Kotlin plugin needed for Compose, so I decided to put both into the mix and see what happened.

对于如此小的应用程序,使用诸如Dagger之类的依赖项注入框架似乎过大了,但是在实际项目中,它应该是构建对象的首选方法。 在这种情况下,使用包含kapt的清晰框架可能会与Compose所需的Kotlin插件发生冲突,因此我决定将两者混合使用,然后看看发生了什么。

The important bit is the use of Picasso (or any other image downloading tool): we normally would call it as close as possible to the view layer, as each of these libraries works best with a reference to the View where the image will be downloaded.

重要的一点是使用Picasso(或任何其他图像下载工具):我们通常将其称为与View层尽可能近的位置,因为这些库中的每一个都以对要下载图像的View的引用为最佳。 。

新方法(?) (The new way(?))

As of today, there is no easy way to provide an image asynchronously with Compose. It is certainly being worked on (as we can understand by the comment left in the code, at least for what concerns loading from resources), but it’s not present in the SDK just yet:

到目前为止,还没有简便的方法可以通过Compose异步提供图像。 它肯定正在开发中(正如我们可以从代码中留下的注释中理解的那样,至少对于从资源加载中所涉及的问题而言),但是它目前尚未在SDK中提供:

A screenshot showing the comment in the documentation
屏幕截图显示了文档中的注释

In an ideal world, I would expect to tell an Image where to fetch its content from and it would automatically show it for me, but it is not yet the case. It wasn’t until now, and it’s certainly not yet the case.

在理想的世界中,我希望告诉Image何处获取其内容,它会自动为我显示它,但事实并非如此。 直到现在,当然还不是这样。

So, I decided to try something different, that could be easily replicable again. Instead of passing down the URL, I would wrap the Picasso call inside a coroutine and download the images before I send the model to the UI, right after the API call:

因此,我决定尝试一些不同的方法,这些方法可以轻松地再次复制。 我不用传递URL,而是将Picasso调用包装在协程中并下载图像,然后再将模型发送到UI,即紧接API调用之后:

黄金三镖客 (The good, the bad, and the ugly)

While this solution works (good), it is a feasible procedure only when we know that the amount of images we are downloading is fairly limited (bad), and it is overall a bad practice (ugly): we don’t want to fetch more data than the amount our users will see, and we certainly would prefer to download the images in a separate chain.

尽管此解决方案有效(良好),但只有当我们知道要下载的图像数量相当有限(不好)并且总体上是不好的做法(丑陋)时,这才是可行的过程:我们不想获取比我们的用户看到的数据量更多的数据,我们当然希望在单独的链中下载图像。

还有一件事… (One more thing…)

Another thing that hit me (in a positive manner indeed!) is the fact that Composable components do not manage the state: as of now, every change to the state should be managed from a specific object, that should be tied to the Composable. Let’s see an example:

令我Composable另一件事(确实是积极的态度!)是Composable组件不管理状态的事实:到目前为止,对状态的每次更改都应从特定对象管理,该对象应与Composable绑定。 让我们来看一个例子:

The important part is related to line 6: if we removed the onValueChange parameter as a whole, we wouldn’t be able to either see what was being typed inside the text field. This is, in my opinion, a huge leap forward: with the current approach, it’s never clear where and when the state of a Widget is saved and updated. Managing the state of a View is no easy task, but the path drawn by declarative UI frameworks will make developing graphical interfaces easier and less chaotic in the long run.

重要的部分与第6行有关:如果整体上删除了onValueChange参数,我们将无法看到在文本字段中键入的内容。 在我看来,这是一个巨大的飞跃:使用当前的方法,永远不清楚在何处以及何时保存和更新Widget的状态。 管理View的状态并不是一件容易的事,但是从长远来看,声明式UI框架绘制的路径将使开发图形界面更容易且不会造成混乱。

结论 (Conclusion)

It is an easy solution (most certainly there are other ways to perform the same task on the web) to a problem that I was facing, and it made me realize that declarative UIs, such as Compose, are bringing a shift in the way we shape our code, and this is something to keep in mind.

这是我遇到的一个简单的解决方案(最肯定的是,还有其他方法可以在网络上执行相同的任务),这使我意识到声明性UI(例如Compose)正在改变我们的方式塑造我们的代码,这是要牢记的。

Furthermore, with this approach, we are certainly closer to the real idea of a ViewModel compared to what we do now, but I’m sure this is only one of the millions of small changes that this new wave of UI frameworks.

此外,通过这种方法,与我们现在所做的相比,我们当然更接近ViewModel的真实概念,但是我敢肯定,这只是新一轮UI框架的数百万个小更改之一。

Thanks to Daniele Bonaldo, Fabio Collini, and Florina Muntenescu for proofreading this post.

感谢 Daniele Bonaldo Fabio Collini Florina Muntenescu 本文 进行校对。

翻译自: https://medium/google-developer-experts/paradigm-shifts-with-declarative-ui-62c609ecccf9

声明式ui

更多推荐

声明式ui_声明式ui的范式转换