欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flutter入门并开发天气预报APP(3)——Widget

程序员文章站 2022-05-30 15:11:50
...

1. 简介

在Flutter中,Widget是个非常基本的东西,我在上一章就说过,Flutter中只要是界面都是Widget,你可以把它就理解成是控件,但是又和Android的View控件不同的是,在Flutter中,包括PaddingAlign、手势检测的GestureDetector等等,都算是Widget

其实大多数时候,你就可以把Widget直接理解成UI控件就行了,因为PaddingAlignGestureDetector等等也都是为UI服务的,你就可以理解成Flutter中只要与UI有关的属性都可以算是控件。

2. Widget的状态

在Android中,我们可以直接通过更新数据来达到刷新UI的目的。但是如果使用Flutter,就像我们前面说的计数器的Demo,如果直接通过StatelessWidget也就是无状态Widget的话,是没法进行刷新UI的,只能写一个死界面,也就是说如果在Flutter中界面写出来的就是一个死界面,只有通过刷新状态才能更新UI。

Widget有两个直接子类:StatelessWidgetStatefulWidget

  • StatelessWidget:这个是无状态Widget,实现build()方法后,就不可再变化,哪怕他的状态改变了。这句话可能有点矛盾,但是我来举个例子,比方说现在有一个StatelessWidget,他的内容就是一个Text,而这个Text的内容则显示了counter这个变量。当这个页面出现的时候,取了当时counter的值并显示了出来,但是我们后续不管counter这个值怎么改变,界面都是不会显示出来的。
  • StatefulWidget:这个是有状态Widget,当你有状态需要改变的时候就可以通过他来改变状态。

State的几种状态:

名称 状态
initState create之后被insert到渲染树时调用的,只会调用一次
didChangeDependencies state依赖的对象发生变化时调用
didUpdateWidget Widget状态改变时候调用,可能会调用多次
build 构建Widget时调用
deactivate 当移除渲染树的时调用
dispose Widget即将销毁时调用

3. StatelessWidget

这个类相对简单,只需要实现build()方法就可以了。

StatelessWidget用于不需要维护状态的场景,也就是说如果他需要显示的某一个参数的值发生变化了他也不变。

class Test extends StatelessWidget {
  Test({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("$title"),
      ),
      body: Text("1234"),
    );
  }
}

上面代码就演示了一个StatelessWidget的例子,功能是根据传入的title在界面的title了上显示出来。只实现了build()方法和构造方法。其中构造方法参数Key是必须得有的,而且如果该Widget还有其他状态的话,也需要写入构造方法。接着调用build()方法,将传入的title在界面的title上显示出来。

例如,如果我们调用它:

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test(title: 'Flutter Demo Home Page'),
    );
  }

结果是:
Flutter入门并开发天气预报APP(3)——Widget

4. StatefulWidget

StatelessWidget相对的就是StatefulWidget。它的重点在于可以根据状态来更新。

他较于StatelessWidget,少了我们常用的build()方法,多了createState()方法。下面我就来讲一下他的用法,我还是拿上面的Test做例子。

class Test extends StatefulWidget {
  Test({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  String _title;

  @override
  void initState() {
    setState(() {
      _title = widget.title;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("$_title"),
      ),
      body: Text("1234"),
    );
  }
}

先看Test类,他继承自StatefulWidget,由于这个页面需要根据传入的参数来显示title,所以有一个状态title,并在构造方法中写入了他。接着调用了createState()方法。这个方法是所有StatefulWidget必须的,主要是为这个Widget创建他对应的State。

于是我们就在下面创建一个新的类,类名叫_TestState,继承自State<Test>。由于Widget有title这个状态,并且需要在界面中显示出来,所以为了降低他们的耦合度,我们在State类中也创建一个叫_title的状态,并_title = widget.title;
接下来是一个initState()方法,这个方法也是State必须的,在上面Widget的状态中我们讲到过,这个是初始化State的,同时在initSate()里面,我们写了一个setState(),也就是说我们告诉Flutter说这个方法里面的参数改变了接着Widget的状态也得改变。最后就是build()方法。

接下来我们调用它:

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test(title: '1234'),
    );
  }

结果是:
Flutter入门并开发天气预报APP(3)——Widget