1. 程式人生 > 其它 >flutter初體驗之編寫的第一個flutter app

flutter初體驗之編寫的第一個flutter app

隨著flutter環境的搭建成功,我趁熱打鐵照著教程做起了第一個app的demo   這個教程分兩步, 第一步 我還是跟他(https://flutter.cn/docs/get-started/codelab)一步步下來,感覺挺有收穫的,編碼習慣,編碼語法之類的;專案也正常執行起來,沒有問題: 第二步  
  1. 像列表新增圖示
  2. 新增互動
  3. 導航到新頁面
  4. 使用themes修改UI
    第一部分的時候,就犯難了 教程裡是元件化的,這個沒有問題,但是在使用widget元件的時候,出現問題了。
Widget _buildRow(WordPair pair) {
  final bool 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, ), // ... 新增程式碼結束 );}
  在使用每個元件UI的時候 都要 new 一下,常規程式碼邏輯中是直接使用的如下  
body: ListView.builder(
  padding: const EdgeInsets.all(
16.0), itemBuilder: /*1*/ (context,i){ if(i.isOdd) return const Divider(); /*2*/ final index = i ~/2; /*3*/ if(index >= _suggestions.length){ _suggestions.addAll(generateWordPairs().take(10));/*4*/ } return ListTile( title: Text( _suggestions[index].asPascalCase, style: _biggerFont, ) ); } ),
// /*1*/ 對於每個建議的單詞對都會呼叫一次 itemBuilder,然後將單詞對新增到 ListTile 行中。在偶數行,該函式會為單詞對新增一個 ListTile row,在奇數行,該函式會新增一個分割線的 widget,來分隔相鄰的詞對。注意,在小螢幕上,分割線看起來可能比較吃力。 // /*2*/ 在 ListView 裡的每一行之前,新增一個 1 畫素高的分隔線 widget。 // /*3*/ 語法 i ~/ 2 表示 i 除以 2,但返回值是整型(向下取整),比如 i 為:1, 2, 3, 4, 5 時,結果為 0, 1, 1, 2, 2,這個可以計算出 ListView 中減去分隔線後的實際單詞對數量。 // /*4*/ 如果是建議列表中最後一個單詞對,接著再生成 10 個單詞對,然後新增到建議列表。 // 對於每一個單詞對,_buildSuggestions() 都會呼叫一次 _buildRow()。這個函式在 ListTile 中顯示每個新詞對,這使你在下一步中可以生成更漂亮的顯示行,詳見本 codelab 的第二部分。
  導致跟著教程編寫的時候一直報錯,於是我去掉了 new  的關鍵字之後,重啟了服務,列表中新增圖示的功能實現了,如下圖   但是這裡沒有互動   完整程式碼
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
 
 
void main() {
  runApp(const MyApp());
}
 
 
class RandomWords extends StatefulWidget{
  const RandomWords({Key? key}): super(key:key);
  @override
  _RandomWordsState createState()=> _RandomWordsState();
}
class _RandomWordsState extends State<RandomWords>{
  final List<WordPair> _suggestions = <WordPair>[];
  final Set<WordPair> _saved = new Set<WordPair>();
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
//  3 導航到新頁面
  void _pushSaved(){
    Navigator.of(context).push(
        MaterialPageRoute<void>(
            builder: (BuildContext context){
              final Iterable<ListTile> titls = _saved.map(
                (WordPair pair){
                  return ListTile(
                      title: Text(
                        pair.asPascalCase,
                        style: _biggerFont,
                      )
                  );
                }
              );
              final List<Widget> divided  = ListTile.divideTiles(
                  context: context,
                  tiles: titls,
                ).toList();
              return Scaffold(
                appBar: AppBar(
                  title: const Text('saved name is huYe'),
                ),
                body: ListView(children: divided),
              );
            }
        )
    );
  }
  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: const Text('Startup Name Cenerator'),
        actions: <Widget>[
          IconButton(onPressed: _pushSaved, icon: const Icon(Icons.list))
        ],
      ),
      body: _buildSuggestions()
    );
  }
 
 
  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: (BuildContext _context, int i) {
          if (i.isOdd) {
            return const Divider();
          }
          final int index = i ~/ 2;
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          return _buildRow(_suggestions[index]);
        });
  }
  // 2.1 新增圖示
  Widget _buildRow(WordPair wp){
    final bool alreadySaved = _saved.contains(wp);
    return ListTile(
      title: Text(
        wp.asPascalCase,
        style: _biggerFont,
      ),
      trailing: Icon(
        alreadySaved? Icons.favorite : Icons.favorite_border,
        color: alreadySaved? Colors.red : null,
      ),
      // 2.2 新增互動
      onTap: (){
        setState(() {//在 Flutter 的響應式風格的框架中,呼叫 setState() 會為 State 物件觸發 build() 方法,從而導致對 UI 的更新
          if(alreadySaved){
            _saved.remove(wp);
          }else{
            _saved.add(wp);
          }
        });
      },
    );
  }
}
 
 
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // 這裡自己用了const 程式碼報錯,應該用final
    return MaterialApp(
      title: 'Startup Name Generators',
      home: const RandomWords(),
      theme: ThemeData(
        primaryColor: Colors.red // 不論如何設定都無效(後續補充這的原因)
      ),
    );