「The Complete 2021 Flutter Development Bootcamp with Dart」学習メモ Part 1：Section1-9


みんな大好きFlutterの人気講座「The Complete 2021 Flutter Development Bootcamp with Dart」、前から知ってはいたのですが英語への苦手意識のため放置、どうやらかなり良い講座のようでこのたび通しでやってみることにしました。全部で30時間近くあるらしいので気長に進めていきます。学習の要点メモをまとめていきます。

https://www.udemy.com/course/flutter-bootcamp-with-dart/

・セクション1：Flutter/Dartの概要説明
Flutterイケてるよ、頑張って学ぼうぜ、という話
参考リンク：
https://github.com/londonappbrewery/Flutter-Course-Resources

・セクション2：環境構築
リンク先手順通り
参考リンク：
https://flutter.dev
https://developer.android.com

・セクション3：main、runApp、MaterialApp、Center、Text等
まずは何事もHello Worldから、2行だけのDartコードというのもある意味新鮮w
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/5cf384c1-7245-8e83-c989-6ab0c8740ac5.png" width=200/>

```dart
import 'package:flutter/material.dart';
void main() {runApp(MaterialApp(home: Center(child: Text('Hello World'),),),);}
```

・セクション4：実機テストのやり方
リンク先手順通り
参考リンク：
https://blog.londonappbrewery.com/troubleshooting-ios-device-testing-for-flutter-38c5da239e62
https://blog.londonappbrewery.com/troubleshooting-android-device-testing-on-windows-a2b5d779df08

・セクション5：Scaffold、AppBar、body、Text、Image、Asset管理、AppIcon等
Scaffoldの骨子を学ぶ、まずは静的なUIの組み立て方を学ぶのは入りやすいと感じた
参考リンク：
https://api.flutter.dev/flutter/material/Scaffold-class.html
https://flutter.ctrnost.com
https://appicon.co

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/f0a74487-70f7-bf70-e110-68656dd95824.png" width=200/>

```dart
import 'package:flutter/material.dart';
void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.orange[100],
        appBar: AppBar(
          title: Text('ぬこしん街道'),
          backgroundColor: Colors.orange,
        ),
        body: Center(
          child: Image(
            image: AssetImage('images/ma.jpg'),
          ),
        ),
      ),
    ),
  );
}
```

・セクション6：StatelessWidget、Container、SafeArea、Column、Row、Icon、Fonts、SizedBox、Card、Padding、ListTile、Divider等
UI続き、よく使うレイアウト系のWidgetを学ぶ、pubspec.yamlのインデントはまじでデリケートだよと強調w
HotReloadの旅行バックの例えがわかりやすかったw
参考リンク：
https://flutter.dev/docs/development/ui/widgets
https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e
https://www.materialpalette.com/icons
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/530bbc63-63b4-c1ed-f413-8aafd91634db.png" width=200/>

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(
      MyApp()
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.teal,
        body: SafeArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Padding(
                padding: const EdgeInsets.all(10.0),
                child: CircleAvatar(
                  radius: 75,
                  backgroundImage: NetworkImage('https://ochanomizucardiology.com/wp-content/uploads/igarashi.jpg'),
                ),
              ),
              Text(
                  'Igarashi Kensuke',
                      style: TextStyle(
                        fontSize: 30,
                        fontWeight: FontWeight.bold,
                        fontFamily: 'MPLUS1p',
                        color: Colors.white,
                      ),
              ),
              Text(
                  'FLUTTER DEVELOPER',
                      style: TextStyle(
                        color: Colors.teal.shade100,
                        fontWeight: FontWeight.bold,
                        fontFamily: 'MPLUS1p',
                        letterSpacing: 2.5,
                      ),
              ),
              SizedBox(
                height: 20,
                width: 150,
                child: Divider(
                  color: Colors.teal[900],
                ),
              ),
              Card(
                margin: EdgeInsets.symmetric(horizontal: 25, vertical: 10),
                child: ListTile(
                  leading: Icon(
                    Icons.phone,
                    color: Colors.teal,
                  ),
                  title: Text(
                    '+81 080-1200-0000',
                    style: TextStyle(
                      color: Colors.teal[900],
                      fontFamily: 'MPLUS1p',
                    ),
                  ),
                ),
              ),
              Card(
                margin: EdgeInsets.symmetric(horizontal: 25, vertical: 10),
                child: ListTile(
                  leading: Icon(
                    Icons.email,
                    color: Colors.teal,
                  ),
                  title: Text(
                    'igaken.com@gmail.com',
                    style: TextStyle(
                      color: Colors.teal[900],
                      fontFamily: 'MPLUS1p',
                      fontSize: 18,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
```
・セクション7：Expanded、Button、関数（引数なし戻り値なし）、変数、データ型、StatefulWidget、setState()、Dart Math library、Random()等
買い出しロボットの例えがわかりやすいw
参考リンク：
https://dartpad.dartlang.org
https://api.dart.dev/stable/2.13.4/dart-math/dart-math-library.html
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/02490b8a-d32c-2c59-c63c-3d3ca1a5963a.png" width=200/>

```dart
import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  return runApp(
    MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.red,
        appBar: AppBar(
          title: Text('Dice'),
          backgroundColor: Colors.red,
        ),
        body: DicePage(),
      ),
    ),
  );
}

class DicePage extends StatefulWidget {
  @override
  _DicePageState createState() => _DicePageState();
}

class _DicePageState extends State<DicePage> {
  int leftDiceNumber = 1;
  int rightDiceNumber = 2;
  
  void changeDice() {
    leftDiceNumber = Random().nextInt(5) + 1;
    rightDiceNumber = Random().nextInt(5) + 1;
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Row(
        children: [
          Expanded(
            child: TextButton(
                onPressed: () {
                  setState(() {
                    changeDice();
                  });
                },
                child: Image.asset('images/dice$leftDiceNumber.png')
            ),
          ),
          Expanded(
            child: TextButton(
                onPressed: () {
                  setState(() {
                    changeDice();
                  });
                },
                child: Image.asset('images/dice$rightDiceNumber.png')
            ),
          ),
        ],
      ),
    );
  }
}
```

・セクション8：ここまでの復習チャレンジ
反復演習大事、特に難しいところはなし
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/d02246ce-e05f-1089-f614-ec7221abc1e4.png" width=200/>

```dart
import 'dart:math';
import 'package:flutter/material.dart';

void main() => runApp(
      MaterialApp(
        home: BallPage(),
      ),
    );

class BallPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue[900],
        title: Text('Ask Me Anything'),
      ),
      backgroundColor: Colors.blue,
      body: Ball(),
    );
  }
}

class Ball extends StatefulWidget {
  @override
  _BallState createState() => _BallState();
}

class _BallState extends State<Ball> {
  int ballNumber = 1;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: () {
          ballNumber = Random().nextInt(4) + 1;
          print(ballNumber);
          setState(() {});
        },
        child: Image.asset(
            'images/ball$ballNumber.png'
        ),
      ),
    );
  }
}
```
セッション9：Dart Packages、関数（引数あり戻り値なし）、関数（引数あり戻り値あり）
買い出しロボットがまた登場、returnでStringやintだけでなくWidgetを返せることを始めて知ったw
参考リンク：
https://pub.dev
https://pub.dev/packages/audioplayers
https://freesound.org
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/b5425119-9717-d087-0f89-f55a72900439.png" width=200/>

```dart
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

void main() => runApp(
    XylophoneApp()
);

class XylophoneApp extends StatelessWidget {

  Widget buildKey({required int soundNumnber, required Color keyColor}) {
    return Expanded(
      child: TextButton(
        onPressed: () {
          final player = AudioCache();
          player.play('note$soundNumnber.wav');
        },
        child: Text(''),
        style: TextButton.styleFrom(
          backgroundColor: keyColor,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        body: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              buildKey(soundNumnber: 1, keyColor: Colors.red),
              buildKey(soundNumnber: 2, keyColor: Colors.orange),
              buildKey(soundNumnber: 3, keyColor: Colors.yellow),
              buildKey(soundNumnber: 4, keyColor: Colors.green),
              buildKey(soundNumnber: 5, keyColor: Colors.teal),
              buildKey(soundNumnber: 6, keyColor: Colors.blue),
              buildKey(soundNumnber: 7, keyColor: Colors.purple),
            ],
          ),
        ),
      ),
    );
  }
}
```
ここまででまだコース全体の1/3程度、長くなったので一旦記事を分けます。
https://qiita.com/igakeso/items/00a5dcca6b40c0a3e644