1.從頭開始創建一個Flutter應用程序.
2.編寫 Dart 代碼.
3.利用外部的第三方庫.
4.使用熱重載加快開發周期.
5.實現一個有狀態的widget,為你的應用增加交互.
6.用ListView和ListTiles創建一個延遲加載的無限滾動列表.
7.創建了一個路由并添加了在主路由和新路由之間跳轉邏輯
8.了解如何使用主題更改應用UI的外觀.
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
class MyAppextends StatelessWidget {
@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),
//? ? ? ? ? child: new RandomWords(),
//? ? ? ? ),
//? ? ? ),
//? ? );
//? }
? Widget build(BuildContext context) {
return new MaterialApp(
title:'Startup Name Generator',
theme:new ThemeData(
primaryColor: Colors.white,
),
home:new RandomWords(),
);
}
}
class RandomWordsextends StatefulWidget {
@override
? createState() =>new RandomWordsState();
}
class RandomWordsState extends State {
final _suggestions = [];
final _saved =new Set();
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) {
final alreadySaved =_saved.contains(pair);
return new ListTile(
title:new Text(
pair.asPascalCase,
style:_biggerFont,
),
trailing:new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red :null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(pair);
}else {
_saved.add(pair);
}
});
},
);
}
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),
);
},
),
);
}
@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'),
actions: [
new IconButton(icon:new Icon(Icons.list), onPressed: _pushSaved),
],
),
body: _buildSuggestions(),
);
}
}