はじめに
本記事ですること、目的
- 公式ドキュメントのチュートリアルをする
- 公式ドキュメントの翻訳ではない
- 諸事情により、いつもと別環境でチュートリアルを進め、スクショを撮り、いつもの環境に送信して記事を編集しているせいで、画質がかなり悪い部分がある。申し訳ないです……。
- 私自身、FlutterもDartも初心者のため、プログラム解説などは一切していない。今後できたらいいなと思っていますが、あまり期待はしないでほしい。
※本当は時間の都合上、公式ドキュメントのチュートリアルを進める予定はなかったが、色々とあって進める時間を手に入れたので進めることにした。色々に関しては、ここでは関係ないので割愛。
注意
もし、プログラムで分からないところ、問題があれば、公式ドキュメントの該当ステップの一番最後にある**Problems?**という部分から、その段階での手本を見ることができます。
本記事のステップ番号と、ドキュメントのステップ番号は対応しているので、そちらを参考にしてください。
0. 作るものの確認&プロジェクトを作る
作るもの
第一段階では、english_wordsというパッケージを用いて、二つのランダムな単語を組み合わせて表示する。
最終的には、二つのランダムな単語の組み合わせをリスト表示にし、スクロールするたびに新しい単語の組み合わせを生成→表示という無限にスクロールできるアプリを作る。
最終イメージはこんな感じ。
プロジェクトを作る
作り方に関しては、以前の投稿を参照。
→試しに一個プロジェクトを作る
1. lib/main.dart
を書き換える
lib/main.dart
の中身をすべて消し、以下をコピペする。
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: const Center(
child: Text('Hello World'),
),
),
);
}
}
実行する
コードを走らせるとHello, worldが出てくることを確認する。
公式ドキュメントに書かれていたコードの解説を一部抜粋
main関数のところにある**=>**について
これは、関数やメソッドの中身が一行の場合に使えるものらしい。
void main(){
runApp(MyApp());
}
と意味的には一緒だと思う。ただ、**=>**を使えば見た目がスッキリする。
これ以外にも色々と解説が書かれていたけど、よく意味が分からなかったので省略。気になる方はStep 1: Create the starter Flutter appの最後、Observations欄を見てほしい。
2. パッケージを入れる
english_wordsというオープンソースのパッケージを使う。ちなみに、オープンソースのパッケージはpub.devに色々とあるらしい。
「Flutter勉強記録2日目~カメラを使って景色を見るだけのアプリを作ってみる~」でもcameraパッケージを使ったが、今回はその方法と違う方法で、パッケージを入れる。多分どちらでもいいんじゃないかな?
pubspec.yaml
を開き、english_words: ^4.0.0
を追加する。
[ターミナル] > [新しいターミナル]からターミナルを開き、flutter pub get
を入力
下みたいな結果が出てきて、パッケージを入れ終わる。
Running "flutter pub get" in tutorial... 612ms
lib/main.dart
に行き、今入れたパッケージをインポートする。
import 'package:english_words/english_words.dart';
を既にあるimport文の近くに書く。
下に出てくる青色の波線は「そのパッケージ使われてないから、消した方がよくね??」という忠告なので無視してOK。
VSCodeだと使われていないものは青色の波線、Android Studioだと灰色の文字になるらしい。
lib/main.dart
を以下に変更する
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: Center(
child: Text(wordPair.asPascalCase),
),
),
);
}
}
変更部分は以下の通り(公式ドキュメントのスクショ)
実行する
真ん中に適当な言葉が生成される。生成される言葉はランダムなので、違っていても気にしなくて大丈夫。
3. 可変ウィジェット(Stateful Widget)の追加
ここ辺りのコードの意味は、よくわからなかった。
世の中には不変ウィジェット(Stateless widgets)と可変ウィジェット(Stateful Widget)があり、
- 不変ウィジェット → 中身を変えられない
- 可変ウィジェット → 中身を変えられる
らしい。不変とか可変とかは、私が適当に翻訳したので、言葉として使われているのか不明。
可変ウィジェットを追加する
lib/main.dart
の一番最後にカーソルを合わせ、stful
と入力する。すると、選択肢にFlutter stateful widget
と出てくるので、これを選択する。
RandomWords
と入力する
二つくらいクラスが追加され、カーソルが増殖するので、その状態でRandomWords
と入力する。
_RandomWordsState
の方を以下のように変更する(アンダーバーついている方)
class _RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
MyAppの方を以下のように変更する
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: Center(
child: RandomWords(),
),
),
);
}
}
ビフォーアフターは以下の通り(これも公式ドキュメントのスクショ)
実行する
先ほどまでと変わらず、ただランダムな単語が表示されるだけのアプリになる
4. ランダムな単語が並ぶリストを作る
ここでは、ユーザがスクロールすると無限に単語を生成するリストを作る。
以下のコードの意味は、私自身もよく分かっていないです。Dart特有?の書き方のせいもあり、公式ドキュメントだけでは、何となくしか意味を理解できませんでした。
記事冒頭でも書いた通り、時間があれば解説記事を探すか、意味を一つずつ調べて解説する記事を作ろうかなと思いますが、あまり期待しないでほしいです。もし、解説している記事をご存知の方がいらっしゃればコメントで教えていただければ助かります。
_RandomWordsState
に_suggestions
と_biggerFont
を追加する
最初二行が追加部分。あとは変更していない。
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[]; //追加部分
final _biggerFont = const TextStyle(fontSize: 18.0); //追加部分
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
_buildSuggestions()
関数を_RandomWordsState
クラスに追加
_buildSuggestions()
関数を。先程追加した2行の後ろに追加する。
_buildSuggestions()
関数以降の部分は変更が無いので省略している。
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
//ここ以降追加部分
Widget _buildSuggestions() {
return 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 _buildRow(_suggestions[index]);
});
}
//追加部分ここまで
//以降省略
_RandomWordsState
に_buildRow()
関数を追加する
_buildRow()
関数を先程追加した部分の直後に追加する。
class _RandomWordsState extends State<RandomWords> {
final _suggestions = <WordPair>[];
final _biggerFont = const TextStyle(fontSize: 18.0);
Widget _buildSuggestions() {
//省略
}
//ここから追加部分
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
//追加部分ここまで
//以降省略
_buildSuggestions()
を使うために、_RandomWordsState
クラスのbuild()
メソッドを改良する
_RandomWordsState
クラスの最後辺りにあるbuild()
を以下のように変更する。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
MyApp
クラスのbuild()
を以下のように変更する
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
home: RandomWords(),
);
}
}
ビフォーアフターは以下の通り(例によって公式ドキュメントのスクショ)
実行する
実行すると、無限にスクロールできる意味不明な組み合わせの英単語リストが出てくる
三日目終わり
やっぱりDartの文法が分からないと辛い。コードの意味が分からない。
未だにウィジェットとかの概念を理解できていない。
ここまでは、どちらかというと目的のものを作るために無理矢理突っ走ってきた感じですが、ここらで少しコード復習タイムを取った方が良い気がする。
そのため、次からはコードの解説記事とかになるかもしれないし、何となくは分かったけど解説できるほど理解できなくて、解説記事は上がらないかもしれない。