さあ今回はFlutterのウィジェットについて学んでいこう!!
前回まではDartの文法についてまとめてきました👇
【Flutter/Dart③】Dart文法をチェックしていこう
この基礎を押さえた上で、ウィジェットの概念と書き方について学んでいきます。
Flutterはこのウィジェットを組み合わせていくことによりアプリを完成させていくので、基礎をしっかり理解していきたいですね。
では早速やっていこう✊
Contents
Widget(ウィジェット)について
✅ Flutterアプリの見た目に関わる部分を構成するパーツ
✅ 単純なウィジェットをツリー構造で組み合わせることで、複雑なUIを構築できる
✅ Widgetクラスは必ず他のWidgetを返すbuildメソッドを持つ
✅ buildメソッドはWidgetの代わりにTextを返すこともできる
✅ Widgetの入れ子でFlutterは構成される
✅ 表示、アクション、バックグラウンド、CSSはWidgetの入れ子で表現する
Widgetの基本構成
Widgetで構成されたFlutterの基本構造は以下のようにイメージすればいいかなと思います(一例です)
StatelessWidget
✅ State(状態)を持たない、値が固定されたウィジェット(静的なWidget)
✅ StatelessWidgetを継承した一つのクラスで構成される
✅ 変数を定義しても、親Widgetから渡されるのみで、自分でその値を更新することはできない
✅ buildメソッドを持ち、”Widget“もしくは”Text“を返す
✅ 返すWidgetはStatefulWidget(MaterialApp ..etc)でもOK
👇以下が”Hello World”を表示するだけの簡単なサンプルコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/* Hello World */ // マテリアルデザインのUIがまとめられたパッケージをインストール // マテリアルデザインについて⇨https://api.flutter.dev/ import 'package:flutter/material.dart'; // runApp:引数のWidgetが全画面表示される void main() => runApp(MyApp()); // ↓この書き方でも可 // void main() { // runApp(MyApp()); // } // 最初に表示するWidgetのクラス(StatelessWidgetを継承) class MyApp extends StatelessWidget { @override //親クラスのビルドメソッドを上書き(BuildメソッドでUIを作成) Widget build(BuildContext context) { //マテリアルデザインのアプリを返り値に設定 return MaterialApp( title: "My Widget App", // アプリのタイトル home: Scaffold( //マテリアルデザインの土台 appBar: AppBar( title: Text("Hello Widget♡"), ), body: Center( child: Text( "Hello World!", style: TextStyle(fontSize: 50), ), ), ), ); } } |
外部パッケージのimport
✅ 外部パッケージを利用する場合、importしてあげる
✅ pubspec.yamlファイルに追加したいパッケージを記述する
✅ ターミナルで”flutter packages get”を実行
1 2 3 4 |
# <main.dart> import 'package:flutter/material.dart'; // 外部パッケージをimport&pubspec.yamlファイルに追加 import 'package:english_words/english_words.dart'; |
1 2 3 4 5 6 7 8 9 10 11 |
# <pubspec.yaml> /* ---------------省略--------------- */ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.0 english_words: ^3.1.5 # パッケージを追記 dev_dependencies: flutter_test: sdk: flutter /* ---------------省略--------------- */ |
1 2 3 |
# <Command> $ flutter packages get $ flutter pub get |
StatefulWidget
✅ ユーザーの操作、通信などによって動的に状態が変わるウィジェット
✅ Widgetにstate概念を入れて拡張したもの
✅ stateが変化した時に再描画を指示するメソッドが組み込まれている
✅ StateクラスとWidgetクラスの2つのクラスで構成されている
✅ buildメソッドを持たないが、createStateメソッドを持つためこれがStateクラスを返す
✅ StatefulWidget自体はシンプルな構造で、複雑な処理等はStateクラスで持つ
✅ Stateクラスで機能的なメソッドを実装する
✅ Stateクラスはbuildクラスを持ち、Widgetを返す時に定義したメソッドを
👇StatefulWidgetの使用例になります
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/* StatefulWidget */ import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; void main() => runApp(MyApp()); // StatefulなWidgetのクラスはStatefulWidgetを継承 class RandomWords extends StatefulWidget { @override // createState():ビルド後に呼ばれるメソッドで必須(型はState) RandomWordsState createState() => RandomWordsState(); } // 状態を管理するクラスは、Stateクラスを継承 class RandomWordsState extends State<RandomWords> { @override Widget build(BuildContext context) { // WordPair:english_wordsパッケージのメソッド final wordPair = WordPair.random(); return Text(wordPair.asPascalCase, style: TextStyle(fontSize: 40)); } } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Stateful App', home: Scaffold( appBar: AppBar( title: Text("Stateful sample App"), ), body: Center( //StatefullWidgetで定義したRandomWordsを表示 child: RandomWords()), ), ); } } |
StatefulWidgetのメソッド構成
Widgetクラス
createState():ビルド後に呼ばれるメソッドで必須 (型はState)
Stateクラス
initState():最初に一度呼ばれる Widgetツリーの初期化を実行
didChangeDependencies():initState()呼び出し直後に呼ばれる Widgetツリーの変更要素に通知する
build():didChangeDependenciesの呼出し後にしか呼ばれない 複数回呼ばれる Widgetツリーを置き換える
didUpdateWidget(Widget oldWidget):リビルド時のinitState()的な位置づけ
setState():任意で呼べるメソッド Widgetツリーを再構成して、変更を反映させる 簡単な変数の代入だけでなく非同期処理でも使える
dispose():Stateを永続的に削除する 画面を落とすときやストリーム停止で使用
Material Design
✅ Googleが提唱したデザインシステム
✅ 『マテリアル=物理的』⇨『現実世界の物理的な法則に則ったデザイン』
直感的に理解しやすいメリット有
✅ Flutterではマテリアルデザイン用のウィジェットが数多く用意されている
⇨https://meterial.io/
ListView
✅ スクロール可能な画面の実装(テーブルビュー)
👇ListViewを使った実装例になります(先ほど学んだStatefulWidgetの応用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/* Listview */ import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; void main() => runApp(MyApp()); //StatelessWidgetでMaterialApp.RandomWords(動的Widget)を返り値で設定する class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: "ListView App", home: RandomWords(), //このメソッドをこの後定義 ); } } // createStateメソッドでRandomWordsState関数を呼び出す class RandomWords extends StatefulWidget { @override RandomWordsState createState() => RandomWordsState(); } //Stateクラス class RandomWordsState extends State<RandomWords> { // 変数に_(アンダーバー)をつけることでnon-public(外部からアクセス不可)とすることができる // ListViewのWidgetを作るメソッド Widget _buildSuggestions() { final _wordPairs = <WordPair>[]; //単語のペアを格納するリスト //itemBuilderで一行ごとに処理が呼ばれ、偶数行の場合にListTileを表示し、奇数行のときにDividerを表示 return ListView.builder(itemBuilder: (context, i) { if (i.isOdd) return Divider(); //奇数行には水平線を表示 final index = i ~/ 2; // Divider線を抜いた行数をカウントする //利用可能な英文リスト数をindexが超えた場合は,追加で10個の英文リストを生成 if (index >= _wordPairs.length) { _wordPairs.addAll(generateWordPairs().take(10)); } return _buildrow(_wordPairs[index]); }); } //_buildSuggestionsのListView.builderの返り値である_buildrowを定義 Widget _buildrow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, )); } // RandomWordsStateクラスのbuildメソッドを以下のように書き換え、_buildSuggestionsメソッドを呼び出すように変更 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Listview sample App"), ), body: _buildSuggestions(), ); } } |
“【Flutter/Dart④】Flutterのウィジェットについて”は以上になります、いかがだったでしょうか?
Widgetは他にも本当に無数にあるので、少しずつ書きながら覚えていくのがいいんじゃないかなと思います。
次回は”Layout”の作り方について説明していきます、楽しみにしてて下さいね✊
今回はこの辺で、バイバイ👋
○Flutter/Dartを勉強していきたい方
○アプリ開発に興味がある方
○筆者と一緒に勉強をしていこうって思っていただける方