Flutterアプリケーション開発概論

【作品データ追加】moviesリストにタイトル・画像・YouTube IDを登録する

8NETFLIX風動画アプリを作りながらUI・検索・動画再生・共有機能を学ぶFlutter(iOS・Android)アプリ開発
FlutteriOSAndroidMacOSWindows基礎から学ぶ開発アプリ開発

この節で学ぶこと

前の節では、MovieItem クラスを使って、作品情報をひとまとまりにする方法を学びました。

今回の節では、その MovieItem を使って、実際に movies リストへ新しい作品データを追加していきます。

アプリのHome画面、Search画面、Clips画面、詳細画面に表示されている作品は、すべて movies というリストから読み込まれています。

つまり、movies に作品を追加すると、アプリに表示される作品も増えます。

今回は、次のような流れで進めます。

完成コードを使う
↓
moviesリストの場所を探す
↓
MovieItemを1つ追加する
↓
タイトル・画像URL・YouTube IDを登録する
↓
保存する
↓
画面の変化を見る
↓
チャレンジ問題に進む

コードを書くというより、まずは「作品データを1件追加すると、アプリの画面にどう反映されるのか」を体験していきましょう。


moviesリストとは?

今回のアプリでは、作品データを movies というリストにまとめています。

コードでは、このような形です。

const movies = [
  MovieItem(
    title: 'Squid Game',
    subtitle: 'Survival thriller series',
    description:
        'Hundreds of cash-strapped players accept a strange invitation to compete in children’s games. Inside, a tempting prize awaits — with deadly high stakes.',
    posterUrl:
        'https://image.tmdb.org/t/p/w500/dDlEmu3EZ0Pgg93K2SVNLCjCSvE.jpg',
    backdropUrl:
        'https://image.tmdb.org/t/p/w1280/oaGvjB0DvdhXhOAuADfHb261ZHa.jpg',
    youtubeVideoId: 'oqxAJKy0ii4',
    year: '2021',
    rating: '18+',
    seasonLabel: 'Season 1',
    category: 'TV Drama',
    matchRate: 98,
    homeCategory: HomeCategory.shows,
  ),
];

この MovieItem(...) が、作品1つ分のデータです。

実際の完成コードでは、この MovieItem(...) が複数並んでいます。

イメージとしては、こうです。

movies
├── Squid Game
├── Stranger Things
├── Money Heist
├── Wednesday
├── Dark
└── The Witcher

ここに新しい MovieItem(...) を追加すると、作品が1つ増えます。


作品データを追加すると、どこに表示される?

movies リストに作品を追加すると、いろいろな画面に反映されます。

画面反映される内容
Home画面横スクロールの作品一覧に表示される
Search画面検索対象になる
Clips画面縦スクロールで表示される
詳細画面タップすると作品詳細が表示される
YouTube再生画面登録したYouTube IDの動画が再生される

つまり、作品データはアプリの中心です。

1つの作品データを追加するだけで、複数の画面に影響します。

この感覚が分かると、アプリ開発がかなり面白くなってきます。


MovieItemに必要な項目

新しい作品を追加するときは、MovieItem に必要な項目をすべて書く必要があります。

今回の MovieItem には、次の項目があります。

項目内容
title作品タイトル'Interstellar'
subtitle短い説明'Space science fiction'
description詳しい説明文'A team travels through space...'
posterUrl縦長ポスター画像'https://...'
backdropUrl横長背景画像'https://...'
youtubeVideoIdYouTube動画ID'zSWdZVtXT7E'
year公開年'2014'
rating年齢制限'13+'
seasonLabelシーズンや作品形式'Movie'
categoryジャンル'Sci-Fi'
matchRateマッチ率97
homeCategoryHome画面のカテゴリHomeCategory.movies

required がついている項目なので、どれか1つでも足りないとエラーになります。


追加用テンプレート

まずは、このテンプレートを使うと分かりやすいです。

MovieItem(
  title: '',
  subtitle: '',
  description: '',
  posterUrl: '',
  backdropUrl: '',
  youtubeVideoId: '',
  year: '',
  rating: '',
  seasonLabel: '',
  category: '',
  matchRate: 90,
  homeCategory: HomeCategory.movies,
),

ここに、作品ごとの情報を入れていきます。

最初から完璧な文章にしなくても大丈夫です。

まずは表示されることを確認するのが大切です。


新しい作品データを追加してみよう

今回は例として、Interstellar という作品データを追加してみます。

movies リストの最後、つまり最後の MovieItem(...) の後ろに追加します。

MovieItem(
  title: 'Interstellar',
  subtitle: 'Space science fiction',
  description:
      'A group of explorers travel through a wormhole in space to find a new home for humanity.',
  posterUrl:
      'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',
  backdropUrl:
      'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',
  youtubeVideoId: 'zSWdZVtXT7E',
  year: '2014',
  rating: '13+',
  seasonLabel: 'Movie',
  category: 'Sci-Fi',
  matchRate: 97,
  homeCategory: HomeCategory.movies,
),

追加するときに大切なのは、前の作品データとの区切りです。

MovieItem(...) の最後には、必ずカンマ , をつけます。

),

このカンマを忘れると、エラーになることがあります。


moviesリストに追加した状態のイメージ

追加後は、ざっくりこのような形になります。

const movies = [
  MovieItem(
    title: 'Squid Game',
    // 省略
    homeCategory: HomeCategory.shows,
  ),
  MovieItem(
    title: 'Stranger Things',
    // 省略
    homeCategory: HomeCategory.shows,
  ),
  MovieItem(
    title: 'Interstellar',
    subtitle: 'Space science fiction',
    description:
        'A group of explorers travel through a wormhole in space to find a new home for humanity.',
    posterUrl:
        'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',
    backdropUrl:
        'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',
    youtubeVideoId: 'zSWdZVtXT7E',
    year: '2014',
    rating: '13+',
    seasonLabel: 'Movie',
    category: 'Sci-Fi',
    matchRate: 97,
    homeCategory: HomeCategory.movies,
  ),
];

実際のコードでは既存の作品がもっとありますが、考え方は同じです。

movies = [ ... ] の中に MovieItem(...) を追加します。


titleを登録する

title は、作品タイトルです。

title: 'Interstellar',

これはHome画面、詳細画面、Search画面などで使われます。

たとえば、Search画面では、この title が検索対象になります。

final title = movie.title.toLowerCase();

そのため、Interstellar と検索すると、この作品が表示されるようになります。


subtitleを登録する

subtitle は、短い説明です。

subtitle: 'Space science fiction',

現在のコードでは大きく目立つ場所にはあまり出てきませんが、作品データとして持っておくと、あとからUIを増やすときに便利です。

たとえば、今後カードの下に短い説明を出したいときに使えます。


descriptionを登録する

description は、作品の詳しい説明文です。

description:
    'A group of explorers travel through a wormhole in space to find a new home for humanity.',

この説明文は、詳細画面やClips画面で表示されます。

長すぎると画面からはみ出しやすくなるので、最初は1〜2文くらいがおすすめです。

日本語にしても大丈夫です。

description:
    '人類の新しい住まいを探すため、宇宙のワームホールを越えて旅をする物語です。',

教材として使うなら、日本語の説明文の方が読みやすいです。


posterUrlを登録する

posterUrl は、縦長のポスター画像です。

posterUrl:
    'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',

この画像は、横スクロールの作品カードで使われます。

Image.network(
  movie.posterUrl,
  width: width,
  height: height,
  fit: BoxFit.cover,
)

posterUrl は縦長画像の方がきれいに表示されます。

横長画像を入れると、作品カードの中で見切れたり、バランスが悪くなったりします。


backdropUrlを登録する

backdropUrl は、横長の背景画像です。

backdropUrl:
    'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',

この画像は、Home画面の大きな背景や、詳細画面、Clips画面などで使われます。

Image.network(
  movie.backdropUrl,
  fit: BoxFit.cover,
)

backdropUrl は横長画像が向いています。

スマホ画面いっぱいに表示するので、背景として使いやすい画像を選ぶときれいです。


YouTube IDを登録する

youtubeVideoId は、YouTube再生に使う動画IDです。

youtubeVideoId: 'zSWdZVtXT7E',

YouTubeのURLが次のような場合、

https://www.youtube.com/watch?v=zSWdZVtXT7E

動画IDは、この部分です。

zSWdZVtXT7E

アプリには、URL全体ではなく、動画IDだけを入れます。

間違いやすいので注意してください。

正しい例:

youtubeVideoId: 'zSWdZVtXT7E',

間違いやすい例:

youtubeVideoId: 'https://www.youtube.com/watch?v=zSWdZVtXT7E',

今回のコードでは、動画IDだけを使う形になっています。


year・rating・seasonLabelを登録する

作品の基本情報も入れます。

year: '2014',
rating: '13+',
seasonLabel: 'Movie',

それぞれの意味は次の通りです。

項目内容
year公開年
rating年齢制限
seasonLabelシーズンや作品形式

映画なら seasonLabel'Movie' でOKです。

ドラマなら、次のように書くことができます。

seasonLabel: 'Season 1',

この情報は、詳細画面のメタ情報として表示されます。


categoryを登録する

category は作品ジャンルです。

category: 'Sci-Fi',

これは、詳細画面やClips画面に表示されます。

また、Search画面の検索対象にもなっています。

final category = movie.category.toLowerCase();

つまり、Sci-Fi と登録しておくと、Search画面で sci-fi と入力したときに見つかります。


matchRateを登録する

matchRate は、作品のおすすめ度のように表示される数字です。

matchRate: 97,

画面では、次のように表示されます。

97% Match

matchRateint なので、クォーテーションで囲みません。

正しい例:

matchRate: 97,

間違いやすい例:

matchRate: '97',

'97' と書くと文字扱いになってしまいます。


homeCategoryを登録する

homeCategory は、Home画面のカテゴリ分けに使います。

homeCategory: HomeCategory.movies,

選べるカテゴリは、次の通りです。

enum HomeCategory {
  all,
  shows,
  movies,
  games,
  newHot,
}

たとえば、映画作品なら、

homeCategory: HomeCategory.movies,

ドラマ系なら、

homeCategory: HomeCategory.shows,

新着っぽく見せたいなら、

homeCategory: HomeCategory.newHot,

というように使えます。


追加した作品を画面で確認する

作品データを追加したら、保存してアプリを確認します。

見るポイントは次の通りです。

確認する場所見る内容
Home画面横スクロール作品一覧に追加されているか
MoviesタブHomeCategory.movies にした場合、Moviesで表示されるか
Search画面タイトルやカテゴリで検索できるか
Clips画面縦スクロールで表示されるか
詳細画面タップした作品の情報が表示されるか
Playボタン登録したYouTube動画が再生されるか

追加したら、まずSearch画面でタイトル検索するのがおすすめです。

たとえば、Interstellar を追加した場合は、Search画面で、

interstellar

と入力してみましょう。

検索結果に表示されれば、データ追加はうまくいっています。


まずカスタマイズしてみよう

今回は、自分の好きな作品を1つ追加してみましょう。

最初は、以下のテンプレートをそのままコピーして、値だけ変えればOKです。

MovieItem(
  title: 'Your Movie Title',
  subtitle: 'Short subtitle',
  description:
      'ここに作品の説明文を入れます。長すぎない文章にすると、画面で読みやすくなります。',
  posterUrl:
      'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',
  backdropUrl:
      'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',
  youtubeVideoId: 'zSWdZVtXT7E',
  year: '2024',
  rating: '13+',
  seasonLabel: 'Movie',
  category: 'Sci-Fi',
  matchRate: 95,
  homeCategory: HomeCategory.movies,
),

まずはタイトルだけ変えて試しても大丈夫です。

動くことを確認してから、画像や説明文を整えていきましょう。


よくあるつまずきポイント

Q. 作品を追加したらエラーが出ました。

まず、すべての項目が入っているか確認してください。

MovieItem には、次の項目が必要です。

title:
subtitle:
description:
posterUrl:
backdropUrl:
youtubeVideoId:
year:
rating:
seasonLabel:
category:
matchRate:
homeCategory:

1つでも足りないとエラーになります。


Q. カンマをどこにつければいいですか?

各項目の最後にカンマをつけます。

title: 'Interstellar',
subtitle: 'Space science fiction',

MovieItem(...) の最後にもカンマをつけます。

),

Dartでは、カンマがあるとコードが見やすくなり、自動整形もしやすくなります。


Q. 画像が表示されません。

まず、画像URLが正しいか確認してください。

画像URLは、ブラウザで開いて画像が表示されるか確認すると分かりやすいです。

また、posterUrl には縦長画像、backdropUrl には横長画像を入れると、画面にきれいに表示されます。


Q. YouTubeが再生されません。

youtubeVideoId に、URL全体ではなく動画IDだけを入れているか確認してください。

OK:

youtubeVideoId: 'zSWdZVtXT7E',

NG:

youtubeVideoId: 'https://www.youtube.com/watch?v=zSWdZVtXT7E',

Q. カテゴリタブに表示されません。

homeCategory を確認してください。

たとえば、

homeCategory: HomeCategory.movies,

にした場合、Moviesタブに表示されます。

Showsタブに出したい場合は、

homeCategory: HomeCategory.shows,

にします。


チャレンジ

チャレンジ1:新しい作品を1つ追加しよう

movies リストの最後に、次のデータを追加してみましょう。

MovieItem(
  title: 'Interstellar',
  subtitle: 'Space science fiction',
  description:
      'A group of explorers travel through a wormhole in space to find a new home for humanity.',
  posterUrl:
      'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',
  backdropUrl:
      'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',
  youtubeVideoId: 'zSWdZVtXT7E',
  year: '2014',
  rating: '13+',
  seasonLabel: 'Movie',
  category: 'Sci-Fi',
  matchRate: 97,
  homeCategory: HomeCategory.movies,
),

保存したら、Home画面とSearch画面で確認してください。


チャレンジ2:説明文を日本語にしよう

追加した作品の説明文を、日本語に変えてみましょう。

変更前:

description:
    'A group of explorers travel through a wormhole in space to find a new home for humanity.',

変更後の例:

description:
    '人類の新しい住まいを探すため、宇宙のワームホールを越えて旅をする物語です。',

チャレンジ3:カテゴリをNew & Hotにしてみよう

次のコードを探してください。

homeCategory: HomeCategory.movies,

これを次のように変えます。

homeCategory: HomeCategory.newHot,

保存して、Home画面の New & Hot タブを押してみましょう。


チャレンジ4:YouTube動画IDを変えてみよう

次のコードを探してください。

youtubeVideoId: 'zSWdZVtXT7E',

別のYouTube動画IDに変更して、Playボタンを押してみましょう。


チャレンジの答え

チャレンジ1の答え

movies リストの最後に、次のように追加します。

MovieItem(
  title: 'Interstellar',
  subtitle: 'Space science fiction',
  description:
      'A group of explorers travel through a wormhole in space to find a new home for humanity.',
  posterUrl:
      'https://image.tmdb.org/t/p/w500/gEU2QniE6E77NI6lCU6MxlNBvIx.jpg',
  backdropUrl:
      'https://image.tmdb.org/t/p/w1280/rAiYTfKGqDCRIIqo664sY9XZIvQ.jpg',
  youtubeVideoId: 'zSWdZVtXT7E',
  year: '2014',
  rating: '13+',
  seasonLabel: 'Movie',
  category: 'Sci-Fi',
  matchRate: 97,
  homeCategory: HomeCategory.movies,
),

Home画面の作品一覧や、Search画面の検索結果に表示されます。


チャレンジ2の答え

変更前:

description:
    'A group of explorers travel through a wormhole in space to find a new home for humanity.',

変更後:

description:
    '人類の新しい住まいを探すため、宇宙のワームホールを越えて旅をする物語です。',

詳細画面やClips画面の説明文が日本語になります。


チャレンジ3の答え

変更前:

homeCategory: HomeCategory.movies,

変更後:

homeCategory: HomeCategory.newHot,

Home画面の New & Hot タブを押したときに表示されるようになります。


チャレンジ4の答え

変更前:

youtubeVideoId: 'zSWdZVtXT7E',

変更後の例:

youtubeVideoId: 'b9EkMc79ZSU',

Playボタンを押したときに、指定したYouTube動画が再生されます。


この節のまとめ

この節では、movies リストに新しい作品データを追加する方法を学びました。

大切なポイントは次の通りです。

  • movies は、アプリで表示する作品データの一覧。
  • 作品1つ分の情報は MovieItem(...) として追加する。
  • title は作品タイトルとして表示される。
  • posterUrl は縦長の作品カード画像に使う。
  • backdropUrl は背景画像として使う。
  • youtubeVideoId はYouTube再生に使う。
  • matchRate は数字なので、クォーテーションで囲まない。
  • homeCategory によって、Home画面のどのカテゴリに表示されるかが決まる。
  • 作品を追加したら、Home画面、Search画面、詳細画面、Playボタンで確認する。

次のステップ

次の節では、下部ナビゲーションで画面を切り替える仕組みを見ていきます。

Home、Clips、Search、My Netaflixの4つの画面を、どのように切り替えているのかを確認します。

アプリらしい操作感を作る大事な部分なので、次も一緒に進めていきましょう。

教材トップへ戻る