• android | 声明式编程!(笔记)


    https://www.jianshu.com/p/c133cb7cac21  讲的不错


    命令式UI (how to do)

    声明式UI (what to do) what to do

    也许有人会说Data Binding不是可以让XML自己"动"起来吗?没有错,Data Binding其实就是Compose诞生之前的一种声明式U方案,谷歌曾经寄希望于通过它来提升U编码效率。

    但是Compose推荐Composable使用首字母大写的名词来命名,且不允许有返回值。


    组合优于继承


    @Composable
    fun HelloComposable() {
        var content by rememberSaveable { mutableStateOf("") }
        HelloContent(content = content, onContentChange = { content = it })
    }

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun HelloContent(content: String, onContentChange: (String) -> Unit) {
        Column {
            Text(text = "Hello $content")
            OutlinedTextField(
                value = content,
                onValueChange = onContentChange,
                label = { Text(text = content) }
            )
        }
    }

    //================================
    Jetpack Compose 遵循单向数据流原则(unidirectional data flow),这是一种用于管理状态和数据更新的设计模式,特别适合用于构建用户界面。在这种模式下,所有的数据更新都应当遵循单个方向的流动,这有几个重要的好处:
    预测性和可理解性: 当数据和状态变化总是以相同的方式流动时,应用的行为变得更加可预测和易于理解。这使得开发者更容易追踪数据流,理解数据是如何、以及在何处被更新的。
    简化状态管理: 在单向数据流中,数据和状态的更新通常集中在特定的地点进行管理,减少了在应用各处分散更新数据引起的混乱和错误。
    容易调试: 由于数据流的一致性,当出现问题时更容易定位和修复错误,因为开发者可以清晰地了解数据从哪里来,以及应该在哪里进行修改。
    在代码示例中,content是作为单一数据源存在的,其值由HelloComposable管理,且通过参数传递到HelloContent中。当在OutlinedTextField中进行输入时,通过onValueChange事件回调更新外部content的状态,从而触发重新渲染(或称为重组,recomposition)过程。由此,我们可以看到数据(content值)是从上层流向下层的,而事件(用户的输入事件)则是从下层流向上层的,导致状态更新并触发重组。
    这种模式确保了组件的UI始终与其状态保持一致,同时也使得状态的更新逻辑变得更加集中和清晰。

    //================================
    单一数据源决定了Composable数据流的单向流动,数据(content)总是自上而下流动,而事件(onContentChange)总是自下而上传递 为什么呢?


    事件(如onContentChange)在Jetpack Compose(或任何现代UI框架)中自下而上传递的概念,主要体现在事件处理和状态管理方面。以OutlinedTextField组件中的onValueChange事件为例,来解析这一点:
    事件回调的定义:在OutlinedTextField组件中,使用onValueChange属性定义了一个事件回调。当用户在文本字段中输入文本时,这个回调函数被触发。
    状态更新:onValueChange通常会被设定为一个更新上层状态的函数,即在您的例子中的onContentChange。这意味着当OutlinedTextField中的事件(例如文本更改)发生时,它会调用onContentChange,这一回调函数随后可能会更新应用的状态(如,更新一个由父组件维护的content变量)。
    自下而上的数据流:OutlinedTextField(作为较“低”层的组件)通过事件(如用户输入)影响了上层状态(通过onContentChange更新content值)。尽管UI框架通常采用自上而下的数据流动(父组件到子组件的状态传递),事件处理却采用自下而上的方式传递,即从子组件回到父组件,并最终可能引起状态的更新和UI的重新渲染。
    响应式UI:一旦上层状态(如content变量)被更新,这个改变通过自上而下的数据绑定(如value = content)自动反映回UI,更新相应组件的显示内容。这样,事件处理和状态管理形成了一个闭环,使得UI能夠实时响应用户的操作。
    总结来说,事件(如onValueChange对应的onContentChange)自下而上的传递体现在它能够影响并更新上层状态,这种机制使得组件能够响应用户的互动,而更新的状态又通过数据绑定机制影响UI的显示,形成一个连贯的响应链条。


    Compose 业务上能做的优化大体上就是这些了。总之我们就是我们要保持组件的颗粒度尽可能的小,容易变动的要独立出来,非常稳定的也要独立出来,尽量使用 Immutable 的数据结构。 如此之后, Compose 的流畅度还是非常不错的。

    //================================
    精简代码 
    编写更少的代码会影响到所有开发阶段:作为代码撰写者,需要测试和调试的代码会更少,出现 bug 的可能性也更小,您就可以专注于解决手头的问题;作为审核人员或维护人员,您需要阅读、理解、审核和维护的代码就更少。

    与使用 Android View 系统(按钮、列表或动画)相比,Compose 可让您使用更少的代码实现更多的功能。无论您需要构建什么内容,现在需要编写的代码都更少了。以下是我们的一些合作伙伴的感想:

    //================================

    “对于相同的 Button 类,代码的体量要小 10 倍。”(Twitter)
    “使用 RecyclerView 构建的任何屏幕(我们的大部分屏幕都使用它构建)的大小也显著减小。”(Monzo)
    ““只需要很少几行代码就可以在应用中创建列表或动画,这一点令我们非常满意。对于每项功能,我们编写的代码行更少了,这让我们能够将更多精力放在为客户提供价值上。”(Cuvva)
    编写代码只需要采用 Kotlin,而不必拆分成 Kotlin 和 XML 部分:“当所有代码都使用同一种语言编写并且通常位于同一文件中(而不是在 Kotlin 和 XML 语言之间来回切换)时,跟踪变得更容易”(Monzo)

    无论您要构建什么,使用 Compose 编写的代码都很简洁且易于维护。“Compose 的布局系统在概念上更简单,因此可以更轻松地推断。查看复杂组件的代码也更轻松。”(Square)
    —— https://developer.android.google.cn/develop/ui/compose/why-adopt?hl=zh-cn

  • 相关阅读:
    Git学习笔记
    Django 的国际化与本地化详解
    IT这个岗位,人才缺口百万,薪资水涨船高,上不封顶
    关于vue中image控件,onload事件里,event.target 为null的奇怪问题探讨
    Mybatis 设计
    C++学习笔记(二十九)
    EFK部署centos7.9(三)Kibana部署
    测试时间不够,你会如何处理?
    c语言:初识结构体
    Mysql 事务的概念-隔离级别-锁
  • 原文地址:https://blog.csdn.net/liuruiaaa/article/details/139912360