第一个简单的示例代码:
1、yaml中添加库文件
cupertino_icons: ^0.1.2
english_words: ^3.1.0
2、
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new RandomWordsState();
}
}
class RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
// 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中
// 在偶数行,该函数会为单词对添加一个ListTile row.
// 在奇数行,该函数会添加一个分割线widget,来分隔相邻的词对。
// 注意,在小屏幕上,分割线看起来可能比较吃力。
itemBuilder: (context, i) {
// 在每一列之前,添加一个1像素高的分隔线widget
if (i.isOdd) return new Divider();
// 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i为:1, 2, 3, 4, 5
// 时,结果为0, 1, 1, 2, 2, 这可以计算出ListView中减去分隔线后的实际单词对数量
final index = i ~/ 2;
// 如果是建议列表中最后一个单词对
if (index >= _suggestions.length) {
// ...接着再生成10个单词对,然后添加到建议列表
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
}
);
}
Widget _buildRow(WordPair pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Appbar'),
),
body: _buildSuggestions(),
);
}
}
StatelessWidget包裹StatefulWidget
Scaffold包含appBar和body
appBar包含title
ListView.builder包含padding和itemBuilder,return ListTile
ListTile包含title和style
忽略itemBuilder中的逻辑以及获取english_words的调用
3、添加交互
final _saved = new Set<WordPair>();
final alreadySaved = _saved.contains(pair);
trailing: new Icon(
Icons.favorite,
color: alreadySaved ? Colors.red: Colors.black,
),
onTap: (){
setState(() {
if(alreadySaved) {
_saved.remove(pair);
} else {
_saved.add(pair);
}
});
},
_saved保存数据Set
onTap中setState为State对象触发RandomWordsState中的build,进行UI更新
4、页面route跳转
void _pushSaved() {
Navigator.of(context).push(
new MaterialPageRoute(builder: (context) {
final titles = _saved.map((pair) {
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
);
final divided = ListTile
.divideTiles(tiles: titles,context: context)
.toList();
return new Scaffold(
appBar: new AppBar(
title: new Text('新的appbar'),
),
body: new ListView(children: divided),
);
})
);
}
actions: <Widget>[
new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved)
],
Appbar添加actions再添加IconButton添加点击方法onPressed
_pushSaved添加MaterialPageRoute通过return一个新的页面包含Appbar和ListView
5、更换主题
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primaryColor: Colors.black,
),
home: new RandomWords(),
);
}
}
MaterialApp中添加theme
primaryColor为主色调
你已经编写了一个可以在iOS和Android上运行的交互式Flutter应用程序。在这个例子中,你已经做了下面这些事:
从头开始创建一个Flutter应用程序.
编写 Dart 代码.
利用外部的第三方库.
使用热重载加快开发周期.
实现一个有状态的widget,为你的应用增加交互.
用ListView和ListTiles创建一个延迟加载的无限滚动列表.
创建了一个路由并添加了在主路由和新路由之间跳转逻辑
了解如何使用主题更改应用UI的外观.
6、自定义控件实现自己想要的UI
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
final Widget title;
@override
Widget build(BuildContext context) {
return new Container(
height: 80.0,
padding: const EdgeInsets.symmetric(horizontal: 8.0,vertical: 16.0),
decoration: new BoxDecoration(color: Colors.blue[500]),
child: new Row(
children: <Widget>[
new IconButton(icon: new Icon(Icons.menu), onPressed: null,tooltip: 'Navigaton menu',),
new Expanded(child: title),
new IconButton(icon: new Icon(Icons.search), onPressed: null,tooltip: 'search',)
],
),
);
}
}
class Myscaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Material(
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'new title',
style: Theme.of(context).primaryTextTheme.title,
),
),
new Expanded(child: new Center(
child: new Text("hello expanded"),
),),
],
),
);
}
}
void main() {
// runApp(new MyApp());
runApp(new MaterialApp(
home: new Myscaffold(),
));
}
为了继承主题数据,widget需要位于MaterialApp内才能正常显示, 因此我们使用MaterialApp来运行该应用。
在MyAppBar中创建一个Container,高度为56像素(像素单位独立于设备,为逻辑像素),其左侧和右侧均有8像素的填充。在容器内部,MyAppBar使用Row布局来排列其子项。 中间的titlewidget被标记为Expanded, ,这意味着它会填充尚未被其他子项占用的的剩余可用空间。Expanded可以拥有多个children, 然后使用flex参数来确定他们占用剩余空间的比例。
MyScaffold通过一个Columnwidget,在垂直方向排列其子项。在Column的顶部,放置了一个MyAppBar实例,将一个Text widget作为其标题传递给应用程序栏。将widget作为参数传递给其他widget是一种强大的技术,可以让您创建各种复杂的widget。最后,MyScaffold使用了一个Expanded来填充剩余的空间,正中间包含一条message。
完