Flutter入門6_YouTubeアプリのトレース

Flutter関連の投稿です。

備忘録として使用する予定ですが
皆さんの解決策にもなれば幸いです。
大まかな基礎編を終えたのでこれまでの入門を復習する形で
YouTubeのトレースを作成しようと思います！

今回はFlutterを使ってYouTubeアプリのトレースです。
※トレースとは原図の上に薄紙を載せ、敷き写しをすることです。私も先ほど調べました笑


## 目次
-完成イメージ
-1.構成
-2.YouTubeアプリのトレース①_first_page.dartの整理
-3.YouTubeアプリのトレース②_AppBarの作成
-4.YouTubeアプリのトレース③_リストの作成
-5.YouTubeアプリのトレース④_画像の引用
-6.YouTubeアプリのトレース⑤_文字や空間の調整
-7.YouTubeアプリのトレース⑥_再生回数と更新日の追加
-8.全体コード
-参考文献
-最後に




# 完成イメージ
・前回の記事からファースト画面にYouTubeアプリのトレースを作成する
　※下記前回記事
 　　今回は前回記事を参考にしなくも可

https://qiita.com/ds0743/items/1af5b4f3de21e4310e6f

・AppBarにYoutube名・アイコンを3つ追加する
・ネットから画像を引用しタイトルと再生回数・投稿日を記載する
・リスト作成時にスクロール機能も付けるようにする
<img width="40%" alt="youtube_view①_GIF.gif" img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/3cb8f9e5-c87f-5d6c-1bee-f1cd8bf53cd9.gif">


## 1. 構成
・first_page.dartのコードを整理をする
・AppBar内にタイトルを記載しアイコンを3つ設置し
　文字色・サイズ・空間を調整する
・ListView.builderを使用しリストを作成する
・Image.Network（）で画像をネットから引用しサイズ調整する
・文字の変更、フォントサイズ、文字の色、空間などを調整する
・再生回数と更新日を追加する

## 2.リスト作成①_first_page.dartの整理
・first_page.dartの不要なWidgetを削除する
```php:first_page.dart
import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue,
        title: const Text('リスト'),
      ),
      body: Container(),
    );
  }
}
```

## 3.YouTubeアプリのトレース②_AppBarの作成
・Textでタイトル名を変更する
・TextStyleで文字色を白にし文字を太くする
・backgroundColorで背景色を黒にする
・actions[]を作成し、その中にIcons.〜でアイコンを追加する
　※厳密にやるならIconButtonが良い
・SizedBox()で空間を調整する
　※空間は8ずつ（8,16,24etc...）調整するとよい

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

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          '凡才プログラマーKBOY',//←タイトルの変更
          style: TextStyle(
            fontWeight: FontWeight.bold,//←文字を太くする
            color: Colors.white,//←文字色を白にする
          ),
        ),
        backgroundColor: Colors.black,//←背景色を黒にする
        actions: [//←actions[]の追加
          Icon(
            Icons.ondemand_video_outlined,//←アイコンの追加
            color: Colors.white,//←アイコンの色を白にする
          ),
          SizedBox(
            width: 24,
          ),//←空間の調整
          Icon(
            Icons.search,
            color: Colors.white,
          ),
          SizedBox(
            width: 24,
          ),
          Icon(
            Icons.menu,
            color: Colors.white,
          ),
          SizedBox(
            width: 24,
          ),
        ],
      ),
      body: Container(),
    );
  }
}
```
<img width="30%" alt="yotube_view②.png" img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/e259cac4-52a8-09d1-acf7-dc0ac1e9920d.png">
※現状のイメージ画像

## 4.YouTubeアプリのトレース③_リストの作成
・colorで背景色を黒にする
・child: ListView.builderでリストを作成する
　※下記を参照してコピーして貼り付けし記載を少し変更すると良い
　　https://api.flutter.dev/flutter/widgets/ListView-class.html
　　<font color="Red">ListViewで作成した場合、スクロール機能は自動で付属される</font>
・TextStyleで文字色を白にする

```php:first_page.dart
      body: Container(
        color: Colors.black,//←背景色を黒にする
        child: ListView.builder(//←リスト作成をする
            padding: const EdgeInsets.all(8),
            itemCount: entries.length,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 50,
                child: Center(
                    child: Text(
                  'Entry ${entries[index]}',
                  style: TextStyle(
                    color: Colors.white,
                  ),//←文字色を白にする
                )),
              );
            }),
      ),
```
・final List<String> entriesを使用してリストに掲載する文字を記載する
　※こちらも下記を参照してコピーして貼り付けし記載を少し変更すると良い
　　https://api.flutter.dev/flutter/widgets/ListView-class.html

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

class FirstPage extends StatelessWidget {
  final List<String> entries = <String>['A','B','C',];//←リストに掲載する文字の記載
  
```
<img width="30%" alt="youtube_view③.png" img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/c05840b2-b218-d57b-daec-8e583fb10263.png">
※現状のイメージ画像

## 5.YouTubeアプリのトレース④_画像の引用
・Center Widgetを消す
・Row Widgetを追加する
・画像のリンクをコピーしてImage.network()で画像を引用する

```php:first_page.dart
      body: Container(
        color: Colors.black,
        child: ListView.builder(
            padding: const EdgeInsets.all(8),
            itemCount: entries.length,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 50,
                child: Row(//←Center Widgetを消してRow Widgetへ変更
                  children: [
                    Image.network(//←画像の引用
                        'https://president.ismcdn.jp/mwimgs/b/7/670/img_b73602ad319d227278d31460bd4ff5be167285.jpg'
                        ),
                    Text(
                      'Entry ${entries[index]}',
                      style: TextStyle(
                        color: Colors.white,
                      ),
                    ),
                  ],
                ),
              );
```

<img width="30%" alt="youtube_view④.png" img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/370d4eee-7eec-d6eb-de12-9348bd306861.png">
※現状のイメージ画像

## 6.YouTubeアプリのトレース⑤_文字や空間の調整
・Containerの高さを調整し画像のサイズを変更する
・paddingで空間を調整する
・Textをentries[index]に変更する
・SizedBoxで文字と画像の空間を調整する
・Row内のTextをExpandedを使用し文字がはみ出さないように調整する
　※Expanded＝左に合わせて余った空間を使用する
 　final List<int> entriesのリストの文字数が多くなるとはみ出してしまうため


```php:first_page.dart
      body: Container(
        color: Colors.black,
        child: ListView.builder(
          padding: const EdgeInsets.all(8),
          itemCount: entries.length,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              height: 100,//←高さの調整
              padding: EdgeInsets.all(8),//←空間の調整
              child: Row(
                children: [
                  Image.network(
                    'https://president.ismcdn.jp/mwimgs/b/7/670/img_b73602ad319d227278d31460bd4ff5be167285.jpg',
                  ),
                  SizedBox(//←文字と画像の空間を調整する
                    width: 16,
                  ),
                  Expanded(//←文字がはみ出さないように調整
                    child: Text(
                      entries[index],//←entries[index]に変更
                      style: TextStyle(
                        color: Colors.white,
                        height: 1.3,
                        fontSize: 16,
                      ),
                      maxLines: 3,
                    ),
                  ),
                ],
              ),
            );
```

・final List<String> entriesの名前を変更する
```php:first_page.dart
import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
    final List<String> entries = <String>[//←文字の変更
    '【キャリア論】登る山を変えるべき時ってあるよね',
    '技術マウントを取るエンジニアさんへの熱い',
    'C',
  ];
```
<img width="30%" alt="youtube_view⑤.png" img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/5b3bf419-d278-2a4e-4db7-e52da64ccf54.png">
※現状のイメージ画像

## 7.YouTubeアプリのトレース⑥_再生回数と更新日の追加

・TextをColumnを使用する
・Textを作成し再生回数と更新日を記載する
・style: TextStyle()で文字の大きさと色を調整する
・Columnを左寄せにする
・Textの文字の大きさを変更し、縦幅と最大行数を設定する

```php:first_page.dart
                  Expanded(
                    child: Column(//←Columnを使用
                      crossAxisAlignment: CrossAxisAlignment.start,//←左寄せ
                      children: [
                        Text(
                          entries[index],
                          style: TextStyle(
                            color: Colors.white,
                            height: 1.3,//←縦幅の設定
                            fontSize: 16,//←文字の大きさの変更
                          ),
                          maxLines: 3,//←最大行数の設定
                        ),
                        Text(//←Textの作成し、再生回数と更新日の作成。
                          '1053回　5日前',
                          style: TextStyle(//←色と文字の大きさの調整
                            color: Colors.grey,
                            fontSize: 12,
                          ),
                        ),
                      ],
                    ),
                  ),

```
これで完成！！！

## 8.全体コード
```php:first_page.dart
import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  final List<String> entries = <String>[
    '【キャリア論】登る山を変えるべき時ってあるよね',
    '技術マウントを取るエンジニアさんへの熱い',
    'C',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          '凡才プログラマーKBOY',
          style: TextStyle(
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
        backgroundColor: Colors.black,
        actions: [
          Icon(
            Icons.ondemand_video_outlined,
            color: Colors.white,
          ),
          SizedBox(
            width: 24,
          ),
          Icon(
            Icons.search,
            color: Colors.white,
          ),
          SizedBox(
            width: 24,
          ),
          Icon(
            Icons.menu,
            color: Colors.white,
          ),
          SizedBox(
            width: 24,
          ),
          Icon(
            Icons.done,
            color: Colors.white,
          ),
        ],
      ),
      body: Container(
        color: Colors.black,
        child: ListView.builder(
          padding: const EdgeInsets.all(8),
          itemCount: entries.length,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              height: 100,
              padding: EdgeInsets.all(8),
              child: Row(
                children: [
                  Image.network(
                    'https://president.ismcdn.jp/mwimgs/b/7/670/img_b73602ad319d227278d31460bd4ff5be167285.jpg',
                  ),
                  SizedBox(
                    width: 16,
                  ),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          entries[index],
                          style: TextStyle(
                            color: Colors.white,
                            height: 1.3,
                            fontSize: 16,
                          ),
                          maxLines: 3,
                        ),
                        Text(
                          '1053回　5日前',
                          style: TextStyle(
                            color: Colors.grey,
                            fontSize: 12,
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}
```

## 参考文献
Flutter大学. 「Flutter超入門2022】⑥今までの復習！YouTubeアプリのトレース【Flutter3.0】」.　YouTube.　2022/06,https://www.youtube.com/watch?v=noWY6aBVY_0,
（参照 2024-06-22）
Flutter. 「ListView class」. 更新日不明,
https://api.flutter.dev/flutter/widgets/ListView-class.html, (参照 2024-06-22)



## 最後に
・はじめにYoutubeの「Flutter大学」の動画を拝見した際に
　これ作れねーだろ！と思いましたが作れました笑
・模写して作成するだけでも
　現状自分が使っているYoutubeアプリの一部分を作成できたことに感動してます！
・Image.Network()を使用した際に画像が反映されなかったのですが
　なぜか再起動をすると上手く行きました
・筆者が分からなくならないように各章ごとに現状イメージを入れました
・次の勉強をFirebaseにするか個人アプリ開発をするか少し迷ってますが
　個人アプリに詰まったら別の勉強を進めようと思います！