第一个Flutter APP

创建Flutter App

创建一个新的Flutter项目,项目会默认自带一个示例,编辑lib/main.dart的代码

删除main.dart文件中的代码,替换为以下代码,然后运行

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home:new Scaffold(
        appBar: new AppBar(
          title: new Text("Welcome to Flutter"),
        ),
        body: new Center(
          child: new Text("Hello world"),
        ),
      ),
    );
  }
}

运行应用程序,设备上看到如下界面:

这里写图片描述
- Flutter提供了一套丰富的Material widgets
- main函数使用了=>符号,这是Dart中单行函数的简写
- 应用继承了StatelessWidget,这代表应用本身也是一个widget,在Flutter中,大多数东西都是widget
- Scaffold是Material library中提供的一个widget,它提供了默认导航栏、标题、包含主屏幕widget树的body属性
- widget提供build方法来描述如何根据其他较低级别的widget来显示自己

使用外部包

如何使用开源软件包,这里以english_words为例
1. pubspec文件用来管理Flutter应用的assets,在pubspec.yaml文件中,添加endlish_words依赖,代码如下:

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  english_words: ^3.1.0
  1. 然后点击上方的Package get,将依赖包安装到项目中
  2. 获取成功之后再main.dart中引入
import 'package:english_words/english_words.dart';
  1. 然后对main.dart项目进行一下更改:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final wordPair=new WordPair.random();
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home:new Scaffold(
        appBar: new AppBar(
          title: new Text("Welcome to Flutter"),
        ),
        body: new Center(
//          child: new Text("Hello world"),
        child: new Text(wordPair.asPascalCase),
        ),
      ),
    );
  }
}
  1. 运行程序,如果程序正在运行可以选择热重载
    这里写图片描述

添加有状态部件(Stateful widget)

StatelessWidget是不可变的,以为着他们的属性不可变,StatefulWidget持有的状态可能在widget生命周期中发生变化实现一个StatefulWidget至少需要两个类:一个StatefulWidget类和一个State类
1. 在main.dart中创建RandomWords的widget

class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new RandomWordsState();
  }
}
  1. 添加RandomWidgetState类,该类持有RandomWord的状态
class RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
    final wordPair = new WordPair.random();
    return new Text(wordPair.asPascalCase);
  }
}
  1. 然后来改造一下之前的代码
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
//    final wordPair = new WordPair.random();
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Welcome to Flutter"),
        ),
        body: new Center(
//          child: new Text(wordPair.asPascalCase),
        child: new RandomWords(),
        ),
      ),
    );
  }
}
  1. 启动应用,观看效果
    这里写图片描述

创建一个ListView

  1. 在RandomWordsState类中添加_suggestions列表保存单词对,在Dart语言中使用下划线前缀表示变量,会强制变成私有,另外添加一个binggerFont变量来增大字体
class RandomWordsState extends State<RandomWords> {
  final _suggestions=<WordPair>[];
  final _biggerFont=const TextStyle(fontSize: 18.0);
}
  1. 在RandomWordsState类中添加_buildSuggestions方法,用来构建ListView
//构建ListView
Widget _buildSuggestions() {
    return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        // 在偶数行,该函数会为单词对添加一个ListTile row.
      // 在奇数行,该行书湖添加一个分割线widget,来分隔相邻的词对。
        itemBuilder: (context, i) {
          if (i.isOdd) {
            return new Divider();
          }
          final index = i ~/ 2;
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          return _buildRow(_suggestions[index]);
        });
  }
  1. 通过_buildRow方法构建一个条目
//构建条目
  Widget _buildRow(WordPair wordPair) {
    return new ListTile(
      title: new Text(
        wordPair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }

4.更新RandomWordsState中的build方法

@override
  Widget build(BuildContext context) {
    //final wordPair = new WordPair.random();
    //return new Text(wordPair.asPascalCase);
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Startup Name Generator"),
      ),
      body: _buildSuggestions(),
    );
  }

5.更新MyApp的build方法,控件交由RandomWrodsState管理

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
//    final wordPair = new WordPair.random();
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new RandomWords(),
    );
  }
}

6.重载应用,查看效果
这里写图片描述

增加交互

为每一个条目增加收藏功能
1. 在RandomWordsState中新增一个_saved集合

final _saved=new Set<WordPair>();
  1. 在_buildRow中添加一个心形图标以启用收藏功能
Widget _buildRow(WordPair wordPair) {
    final saved = _saved.contains(wordPair);
    return new ListTile(
      title: new Text(
        wordPair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        saved ? Icons.favorite : Icons.favorite_border,
        color: saved ? Colors.red : null,
      ),
    );
  }
  1. 给心形图标设置点击事件,图标被点击时调用setState()通知框架状态已经改变
 Widget _buildRow(WordPair wordPair) {
    final saved = _saved.contains(wordPair);
    return new ListTile(
      title: new Text(
        wordPair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        saved ? Icons.favorite : Icons.favorite_border,
        color: saved ? Colors.red : null,
      ),
      onTap: (){
        setState(() {
          if(saved){
            _saved.remove(wordPair);
          }else{
            _saved.add(wordPair);
          }
        });
      },
    );
  }

这里写图片描述

导航到新页面

在Flutter中,导航器管理应用程序的路由栈,将路由推入到导航器的栈中,将会显示更新为该路由界面。从导航器的栈中弹出路由,将显示返回到前一个路由

  1. 在RandomWordsState的build方法中为AppBar添加一个列表图标,当用户点击图标时,进入收藏夹页面
@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Startup Name Generator"),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved)
        ],
      ),
      body: _buildSuggestions(),
    );
  }
  1. 当用户点击导航栏中的列表图标时,建立一个路由并推入到导航器管理栈中。新页面的内容在MaterialPageRoute的build属性中构建。
 void _pushSaved() {
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      final tiles = _saved.map((pair) {
        return new ListTile(
          title: new Text(
            pair.asPascalCase,
            style: _biggerFont,
          ),
        );
      });
      final divided =
          ListTile.divideTiles(context: context, tiles: tiles).toList();
      return new Scaffold(
        appBar: new AppBar(
          title: new Text("Saved Suggestions"),
        ),
        body: new ListView(children: divided),
      );
    }));
  }

这里写图片描述

更改UI主题

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      theme: new ThemeData(
        primaryColor: Colors.white,
      ),
      home: new RandomWords(),
    );
  }
}

这里写图片描述

项目源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值