首页新闻动态正文

Flutter教程2【黑马web前端】

更新时间:2019年07月26日 11时16分43秒 来源:黑马程序员论坛

给IDE安装插件
我使用vsCode,安装Futter和Dart两个插件,你也可以使用Android Studio IDE或者IntelliJ,也需要安装插件。
创建一个基于模版的Flutter app
在你的项目文件夹下打开终端,输入 flutter create 你的app名称。比如 cd Desktop/www && flutter create firstapp。
用IDE打开项目,你主要编辑的是 lib/main.dart 文件。
Hello World
按照惯例,我们写一个 Hello World。
首先删除 lib/main.dart 内的内容,然后输入

import 'package:flutter/material.dart';

void main() => runApp(new Center(
    child: new Text('Hello World', textDirection: TextDirection.ltr),
));

终端运行 flutter run,效果如下图
1. 代码中使用了runApp函数,runApp函数接受指定的控件(Widget),并使其作为控件树(widget tree)的根控件。控件(Widget)定义一个元素(Element)的配置,在Flutter框架的层次结构中处于核心层。本实例中,控件树(widget tree)包含两个控件,Center控件使其子控件处于中间位置,Text控件打印文本内容。runApp函数强制将根控件覆盖屏幕,这意味着文本将显示在屏幕中心。
2. main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写。
3. import 'package:flutter/material.dart',引入Flutter提供的一套丰富的Material widgets。
创建一个书单列表应用
1. 定义一个展示类 Book.dart
import 'package:flutter/material.dart';

// 声明一个 Book 类
class Book {
    // 声明一个常量构造函数
    const Book({this.name});
    final String name;
}
// 重命名一个具有两个参数的来自父控件的回调函数CartChangedCallback,两参数分别为自定义的Book类和布尔型,
typedef void CartChangedCallback(Book book, bool inCart);

// 定义一个扩展自Flutter无状态组件的类 BookItem
class BookItem extends StatelessWidget {
    // 声明构造函数,并调用超类为每一个book实例增加一个key
    BookItem({Book book, this.inCart, this.onCartChanged})
        : book = book,
          super(key: new ObjectKey(book));
    final Book book;
    final bool inCart;
    final CartChangedCallback onCartChanged;

    // 定义一个颜色方法
    Color _getColor(BuildContext context) {
        return inCart ? Colors.black54 : Theme.of(context).primaryColor;
    }

    // 定义一个文本样式方法
    TextStyle _getTextStyle(BuildContext context) {
        if (!inCart) return null;
        return new TextStyle(
            color: Colors.black54,
            decoration: TextDecoration.lineThrough,
        );
    }

    // 重写一个 Widget
    @override
    Widget build(BuildContext context) {
        return new ListTile(
            onTap: () => onCartChanged(book, !inCart),
            leading: new CircleAvatar(
                backgroundColor: _getColor(context),
                child: new Text(book.name[0]),
            ),
            title: new Text(book.name, style: _getTextStyle(context)),
        );
    }
}

BookItem控件遵循无状态控件的通用模式,将在构造函数中接收到的值存储在final成员变量中,然后在build函数执行时使用。
当用户点击列表项时,控件不会直接修改inCart的值,但是控件从父控件接收onCartChanged函数。此模式允许你在控件较高的层次结构中存储状态,这样使状态的持续时间更长。在极端情况下,存储在runApp的控件状态在应用程序的生命周期内保持不变。
当父控件接收到onCartChanged回调,父控件会更新其内部状态,这将触发父控件重建并使用新的inCart值创建BookItem的新实例。尽管父控件在重建时创建了BookItem的新实例,但该操作很节省,因为框架会将新构建的控件与之前构建的控件时进行比较,并将有差异的部分应用于底层渲染对象。
2. 编写父控件 mian.dart
import 'package:flutter/material.dart';
// 引入Book.dart
import 'Book.dart';

// 定义一个扩展自有状态控件的 BookList 类
class BookList extends StatefulWidget {
    BookList({Key key, this.books})
        : super(key: key);
    final List<Book> books;
    @override
    _BookListState createState() => new _BookListState();
}
class _BookListState extends State<BookList> {
    Set<Book> _bookCart = new Set<Book>();
    void _handleCartChanged(Book book, bool inCart) {
        setState(
            () {
            if (inCart)
                _bookCart.add(book);
            else
                _bookCart.remove(book);
        });
    }
    @override
    Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
                title: new Text('书单列表'),
            ),
            body: new ListView(
                children: widget.books.map(
                    (Book book) {
                        return new BookItem(
                            book: book,
                            inCart: _bookCart.contains(book),
                            onCartChanged: _handleCartChanged,
                        );
                    }
                ).toList(),
            ),
        );
    }
}
final List<Book> _kBooks = <Book>[
    new Book(name: '你倾城一笑惊绝了多少年华'),
    new Book(name: '她被你一笑绝经了多少年头'),
    new Book(name: '我看你俩是昏厥了多少岁月'),
    new Book(name: '他看着我们懵逼了多少时光'),
    new Book(name: '所有人梦里花落了多少年少'),
];

void main() => runApp(new MaterialApp(
    title: '我的应用',
    home: new BookList(books: _kBooks),
));

类BookList继承了StatefulWidget,这意味着这个控件存储可变状态,当BookList首次插入到树中,框架调用createState函数在树中相关联的位置创建一个新的_BookListState实例。当该控件的父控件重建时,父控件会创建一个新的BookList实例,但框架将重用已经在树上的_BookListState实例,而不会再次调用createState函数。
要访问当前BookList的属性,_BookListState可以使用其config属性。如果父控件重建并创建一个新的BookList,_BookListState也将使用新的config值重建。如果想要在config属性更改时收到通知,可以覆盖didUpdateConfig函数,它通过oldConfig将旧配置与当前config进行比较。
当处理onCartChanged回调时,_BookListState通过从_bookCart中添加或删除一个产品来改变其内部状态。为了向框架通知它改变了内部状态,它在setState中封装这些调用。调用setState将控件标记为dirty,并安排它在应用程序下次需要更新屏幕时重建。如果在修改控件内部状态时忘记调用setState,框架不会知道控件是dirty的,可能不会调用控件的build函数,这意味着用户界面不会更新以反映更改的状态。
通过这种方式管理动态,不再需要单独编写代码来创建和更新子控件。相反,只需要实现构建函数,即可处理这两种情况。
以下是最终效果图


推荐了解热门学科

java培训 Python人工智能 Web前端培训 PHP培训
区块链培训 影视制作培训 C++培训 产品经理培训
UI设计培训 新媒体培训 产品经理培训 Linux运维
大数据培训 智能机器人软件开发




传智播客是一家致力于培养高素质软件开发人才的科技公司“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。

传智播客从未停止思考

传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”

中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。

何为中高级程序员课程?

传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。




黑马程序员热门视频教程【点击播放】

Python入门教程完整版(懂中文就能学会) 零起点打开Java世界的大门
C++| 匠心之作 从0到1入门学编程 PHP|零基础入门开发者编程核心技术
Web前端入门教程_Web前端html+css+JavaScript 软件测试入门到精通


在线咨询 我要报名
和我们在线交谈!