Flutter ウィジェット

# 元記事

https://docs.flutter.dev/get-started/fundamentals/widgets

# はじめに

Flutterを始めるために，flutterの実装言語であるDartとFlutter UIの構成要素であるウィジェットについて慣れ親しむ必要がある．
どちらもこのページで紹介されるが，このシリーズを通して学び続けることになるだろう．
その他の情報はこのページ全体に書かれているが，学び続けるためにそれぞれの専門家になる必要はない．

# ウィジェット

Flutterに関して，すべてはウィジェットであるということをしばしば聞くだろう．
ウィジェットはFlutterアプリのユーザインタフェースの構成要素であり，それぞれのウィジェットはユーザインタフェースの一部を変更不可の宣言（イミュータブルな宣言）としたものである．
ウィジェットはユーザインタフェースの全ての側面を説明するために使われる．
パディングやアラインメントのようなレイアウト調整やテキストやボタンといった物理的な側面もある．

ウィジェットは構成を基に階層を成す．
それぞれのウィジェットはその親ウィジェットの中で入れ子構造を作り，親ウィジェットから属性を引き継ぐことができる．
この構造はルートウィジェットまで続く．
以下は例である．
```dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp( // Root widget
      home: Scaffold(
        appBar: AppBar(
          title: const Text('My Home Page'),
        ),
        body: Center(
          child: Builder(
            builder: (context) {
              return Column(
                children: [
                  const Text('Hello, World!'),
                  const SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      print('Click!');
                    },
                    child: const Text('A button'),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}
```

上記のコードでは，全てのインスタンス化されたクラスはウィジェットである．
* MaterialApp
* Scaffold
* AppBar
* Text
* Center
* Builder
* Column
* SizedBox
* ElevatedButton

# ウィジェットの構成

これまでで述べたように，Flutterはウィジェットを構成単位として重視している．
ウィジェットは典型的には，強力な効果を生み出すために数多くの一つの目的のウィジェットを組み合わせ，構成される．

```Padding```，```Alignment```，```Row```，```Grid```のようなレイアウトウィジェットがある．
これらのレイアウトウィジェットは，それら自身に視覚的な表現は持っていない．
その代わり，それらの唯一の目的は他のウィジェットレイアウトのいくつかの側面をコントロールすることである．
Flutterはこの構成的なアプローチを活用する実践的なウィジェットを含む．
例えば，一般的に使われるウィジェットである```Container```はレイアウト・ペインティング・ポジショニング・サイジングを担当する複数のウィジェットで構成されている．
いくつかのウィジェットは視覚的な表現を持つ．
例えば，```ElevatedButton```，```Text```，```Icon```，```Image```がある．

もし上記のコード例を走らせると，Flutterは縦置きで画面中央に"Hello World!"というテキストとボタンを描く．

これらの要素を配置するために，利用可能なスペースの中央に子要素を配置する```Center```ウィジェットと，子要素を縦に次々と配置する```Column```ウィジェットがある．
<img src="https://docs.flutter.dev/assets/images/docs/fwe/simple_composition_example.png">

このシリーズの次のページで，Flutterにおけるレイアウトをもっと学ぶ．

# ウィジェットを組み立てる

Flutterでユーザインタフェースを作るために，ウィジェットオブジェクトの```build```メソッドをオーバーライドする．
すべてのウィジェットクラスは```build```メソッドを持っており，他のウィジェットを返さなければならない．
例えば，いくつかのパディングを加えたスクリーンにテキストを追加したければ，以下のように記述できるだろう．
```dart
class PaddedText extends StatelessWidget {
  const PaddedText({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: const Text('Hello, World!'),
    );
  }
}
```

このウィジェットが作られたときとウィジェットに渡される状態などの依存関係が変化したときに，フレームワークは```build```メソッドを呼ぶ．
このメソッドはすべてのフレームで呼ばれる可能性があり，ウィジェットを構築する以上の副作用はないはずである．
Flutterにおけるウィジェットの表示方法は以下のサイトを参考にすること．
https://docs.flutter.dev/resources/architectural-overview

# ウィジェットの状態

このフレームワークは，ステートフルウィジェットとステートレスウィジェットという2つの主要なクラスのウィジェットを導入している．

毎回変更するクラス変数を持たないような，変更可能状態を持たないウィジェットは```StatelessWidget```のサブクラスとなる．
```Padding```や```Text```，```Icon```など多くの組み込みウィジェットはステートレスである．
ウィジェットを作ったときに，多くの場合```StatelessWidget```クラスとなるだろう．

その一方で，ウィジェットのユニークな特性が，ユーザーインタラクションまたは他の要因に基づいて変更される必要がある場合，そのウィジェットはステートフルである．
例えば，ユーザがボタンをタップしたときに値が増えるカウンタをウィジェットが持っているとき，そのウィジェットにとってカウンタの値は状態である．
その値が変化したとき，UIの一部を更新するためにウィジェットは再構築される必要がある．
そのようなウィジェットは```StatefulWidget```のサブクラスとなり，変更可能な状態は```State```サブクラスである別のクラスに格納される．
```StatefulWidget```は```build```メソッドは持たないが，これらのユーザインタフェースは```State```オブジェクトを通して構築される．
以下は例である．
```dart
class CounterWidget extends StatefulWidget {
  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Text('$_counter');
  }
}
```

Stateオブジェクトを変更可能な状態にする（たとえば、カウンターをインクリメントする）ときはいつでも，```setState```を呼び出して，```State```の```build```メソッドを再度呼び出してユーザーインターフェイスを更新するようにフレームワークにシグナルを送る必要がある．

ウィジェットオブジェクトから状態を分離することで，他のウィジェットは，状態を失うことを気にすることなく，ステートレスなウィジェットもステートフルなウィジェットもまったく同じように扱うことができる．
状態を保持するために子を保持する必要がない代わりに，親は子の永続的な状態を失うことなく，いつでも子の新しいインスタンスを作成できる．
フレームワークは必要に応じて既存のステートオブジェクトを見つけて再利用するすべての作業を行う．

```StatefulWidget```クラスは今後のセッションで説明する．

# 重要なウィジェット

Flutterウィジェットは組み込みウィジェットがある．
```Text```のようなUIの最小単位からレイアウトウィジェット，アプリケーションをスタイリングするウィジェットまである．
以下のウィジェットは，学習経路の次のレッスンに進むにあたって最も重要なものである．

* Container
* Text
* Scaffold
* AppBar
* Row and Column
* ElevatedButton
* Image
* Icon

# 次 : レイアウト

このページは，ウィジェットのようなFlutterの基本的なコンセプトの紹介であり，FlutterとDartのコードを読むことに慣れるのに役立つ．
これ以降では特定のトピックについて深く掘り下げる．
次のセクションでは，Flutterでより複雑なレイアウトを作ることで，より面白いUIを作り始める．

このページで学んだことを練習したい場合は，Building user interfaces with Flutterを読んでみよう．