likes
comments
collection
share

面向Android开发者的Flutter——Views(一)

作者站长头像
站长
· 阅读数 9

最近几天开始记录一下一些基础的内容。

我相信很多人都和我差不多,使用Flutter都是简单看一下文档,了解一下widget,然后开始实践做项目,之后遇到问题查问题解决一下,继续做项目。

实践虽然是最快的上手方式,但是慢慢的发现瓶颈,有些问题如果网络上搜索不到,就很难解决。

更有甚者,当遇到一些问题解决不了,就说这个语言不怎么样,这样的问题都解决不了。偶尔还会和同行们吐槽,这就是UI的语言,有些问题就是没办法处理的很好...

我开始反思,真的是语言本身的缺陷吗?会不会是我自己对于一些基础理解的比较浅,才妄下定论?

带着这个思考,我开始查缺补漏,开始思考一些原理性的问题,希望自己能找到答案。

今天针对Views来解答一些问题

什么相当于Flutter中的视图

在Android中,View是屏幕上显示的所有内容的基础。按钮、工具栏和输入,一切都是视图。在Flutter中,可以大体把ViewWidget视为等价。Widget并不完全映射到Android视图,但是当你熟悉Flutter的工作原理时,你可以将他们视为“你声明和构建UI的方式”。

这里面遗留一个小问题,什么是声明式UI、什么是反应式?

然而,和Android的View相比,还是有很多不同的地方。首先,Widget具有不同的生命周期:它们是不可变的,一直存在到它们需要改变的。每当Widget或其状态发生变化时,Flutter的框架都后悔创建一个新的小部件实例树。相比之下,Android视图只会值一次并且在invalidate调用之前不会重绘。

Flutter的小部件是轻量级的,部分原因在于它们的不变性。因为它们本身不是视图,也没有直接绘制任何东西,而是对UI及其语义的描述,这些描述时被inflated到引擎下的实际视图对象中。

Flutter包含Material Components库。这些是实现Material Design 指南的小部件。Material Dessign是一个灵活的设计系统,针对包括iOS在内的所有平台进行了优化。

但Flutter的灵活性和表现力足以实现任何设计语言。例如,在iOS上,可以使用Cupertino 小部件 来生成类似于Apple 的 iOS 设计语言的界面。

如何更新Widget?

在Android中,你可以通过直接改变视图来更新它们。然而,在Flutter中,Widget是不可变的并且不会直接更新,相反你必须使用widget的状态。

这就是Stateful``Stateless widget概念的由来。StatelessWidget就像它听起来那样————一个没有状态信息的widget。

StatelessWidget当你描述的用户界面部分不依赖于对象中的配置信息以外的任何内容时,这很有用。

例如。在Android中,类似于放置一个带logoImageViiew,logo在运行时不会更改,相对应在Flutter用StatelessWidget

如果你想根据在进行HTTP调用或用户交互后接收到数据状态更改UI,那么你必须使用StatefulWidget并告诉Flutter框架小部件State已更新,以便它可以更新该小部件。

这里要注意的重要一点是,无状态和有状态小部件的核心行为是相同的。它们重建每一帧,不同之处在于StatefulWidgget有一个State对象可以跨帧存储状态数据并恢复它。

如果你有疑问,请始终记住这条规则:如果小部件发生变化(例如,由于用户交互),它是 stateful。然而,如果一个小部件对变化做出反应,如果它本身不对变化做出反应,那么包含它的父小部件仍然可以是stateless。

下面一个例子,显示如何使用StatelessWidget,一个常见StatelessWidget的是Text小部件。如果你查看Text小部件的实现,你会发现它是StatelessWidget的子类。

Text(
    'I like Flutter!',
    style: TextStyle(fontWeight: FontWeight.bold),
)

如你所见,Text没有与之关联的状态信息,它只呈现其构造函数传递的内容,仅此而已。

但是,如果你想让“I like Flutter”动态变化怎么办,例如当点击一个FloatingActionButton

为此,将Text小部件包装在一个StatefulWidget并在用户单击按钮时更新它。

import 'package:flutter/material.dart';

void main() {
    runApp(const SampleApp());
}

class SampleApp extends StatelessWidget {
    const SampleApp({super.key});
    
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Sample App',
            theme: ThemeData(
                primarySwatch: Colors.blue,
            ),
            home: const SampleAppPage(),
        );
    }
}

class SampleAppPage extends StatefulWidget {
    const SampleAppPage({super.key});
    
    @override
    State<SampleAppPage> createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
    // Default placeholder text
    String textToShow = 'I like Flutter';
    
    void _updateText() {
        setState(() {
            // Update the text
            textToShow = 'Flutterr is Awesome!';
        });
    }
    
    @override
    Widget build() {
        return Scaffold(
            appBar: AppBar(
                title: const Text('Sample App'),
            ),
            body: Center(child: Text(textToShow)),
            floatingActionButton: FloatingActionButton(
                onPresed: _updateText,
                tootip: 'Update text',
                child: const Icon(Icons.update),
            ),
        );
    }
}

面向Android开发者的Flutter——Views(一)