Flutterの基礎をまとめてみた（３）

# Flutterのカウンターアプリについて

次は、Flutterで新しいプロジェクトを作ったときに自動で作られる「カウンターアプリ」について見ていきます。

### カウンターアプリって何？
![スクリーンショット 2024-11-07 14.50.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/9be21d2f-81a7-6b6a-6ef6-88a5459f514d.jpeg)

カウンターアプリは、ボタンを押すたびに数字が増える、とてもシンプルなアプリです。Flutterを学ぶときに最初に見ることが多いアプリで、どんなふうにアプリが動くかを知るための良い例です。

例えば、このアプリでは画面の中央に大きな数字が表示されています。そして、その下にあるボタンをタップすると、数字が1つずつ増えていきます。こうすることで、Flutterの基本的な画面作りや、ボタンを押したときにどう動くかなどを学ぶことができます。

### カウンターアプリの動き方
Flutterのカウンターアプリでは、ボタンを押すと以下のような動きが見られます：

<div style="display: flex; gap: 10px;">
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/0a4765c4-1384-fe6b-b862-4215bb61117c.jpeg" width="300">
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/523d48c1-f8ee-8e6e-98e4-2cac83b84b25.jpeg" width="300">
</div>


1. 画面の真ん中に「0」と書かれた大きな数字があります。
2. 下のボタンを押すと、この数字が「1」、「2」、「3」…と増えていきます。
3. この「数字が増える」動きによって、アプリのどこが変わったかを見ながらFlutterの仕組みを理解できます。

### どうしてカウンターアプリなの？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/86d1e573-64e2-42f6-4e86-fe2cb6bc6d2a.png" width="300">


カウンターアプリが最初に出てくる理由は、簡単に使えて動きがわかりやすいからです。ボタンを押すと数字が増えるだけなので、Flutterの動きを観察しながら「この部分はこうやって動くんだ」というのを確認できます。

例えば、ボタンを押したときにどのコードが動いているのか、数字がどのように変わっているのかを学ぶことで、アプリの作り方の基本を理解できます。

---

Flutterのカウンターアプリはシンプルで分かりやすいので、初めてプログラミングを学ぶ人にもぴったりです。次にコードを解説します。
コード一覧です。
```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
```



## Flutterのカウンターアプリのコードを1行ずつ丁寧に説明します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/50685e24-1a5d-e8aa-9cb2-186f63aef775.jpeg" width="600">


```dart
import 'package:flutter/material.dart';
```
- Flutterの「material」というものを使いますよ、という意味です。このmaterialにはアプリを作るためのたくさんの便利な道具が入っています。

```dart
void main() {
  runApp(const MyApp());
}
```
- `main()`という部分は、プログラムをスタートさせる場所です。`runApp()`で、私たちが作るアプリを画面に表示させます。

```dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});
```
- `MyApp`という名前のアプリの設計図を作っています。この設計図は「動かない」設計図(`StatelessWidget`)です。つまり、動かすだけで中身が変わりません。

```dart
@override
Widget build(BuildContext context) {
```
- `build`という部分は、このアプリがどう見えるかを作るところです。ここで画面の見た目を決めます。

```dart
  return MaterialApp(
    title: 'Flutter Demo',
```
- アプリの画面を作るために`MaterialApp`を使います。そして、アプリの名前を「Flutter Demo」としています。

```dart
    theme: ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      useMaterial3: true,
    ),
```
- アプリの色のテーマを決めます。今回は紫色(`deepPurple`)を使っています。

```dart
    home: const MyHomePage(title: 'Flutter Demo Home Page'),
  );
}
```
- アプリが最初に表示するページを`MyHomePage`にしています。このページのタイトル（画面の上の部分に表示される文字）を「Flutter Demo Home Page」にしています。

```dart
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;
```
- 次に、`MyHomePage`というページを作っています。このページは「動くページ」(`StatefulWidget`)です。つまり、このページの中身は変わります。

```dart
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
```
- このページの動き方を決める部分を`_MyHomePageState`という名前で作りますよ、という意味です。

```dart
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
```
- ページの中で使う数字を`_counter`という名前で作ります。この数字は最初は「0」です。

```dart
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
```
- `incrementCounter`という名前の関数を作ります。ボタンが押されたときに`_counter`という数字を「1つ」増やします。このとき、画面を新しく作り直して数字が増えたのを見せます。

```dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
```
- ページ全体の見た目を作るところです。この`Scaffold`という部分は、アプリの基本的な枠組みを作ります。

```dart
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
```
- 画面の一番上にあるバー（`AppBar`）を作っています。タイトルには`widget.title`、つまり「Flutter Demo Home Page」と表示されます。

```dart
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
```
- ページの真ん中に色々なものを表示します(`Center`)。この中に縦に並べる形（`Column`）で、文字や数字を配置します。

```dart
            const Text(
              'You have pushed the button this many times:',
            ),
```
- 最初に、「あなたはボタンをこんなにたくさん押しました」というメッセージを表示します。このメッセージは変わらないので`const`（固定された）としています。

```dart
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
```
- 次に、数字を表示します。この数字は`_counter`で、ボタンを押すたびに増えていきます。

```dart
          ],
        ),
      ),
```
- 上にある文字と数字を全部まとめて、画面の真ん中に置きます。

```dart
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
```
- 画面の右下にボタンを作ります（`floatingActionButton`）。このボタンを押すと、`_incrementCounter`が動いて数字が増えます。ボタンの見た目は「+」のマークです。

## まとめ
最後にまとめると以下になります。

```dart
import 'package:flutter/material.dart'; // Flutterのmaterialという便利なツールを使います

void main() {
  runApp(const MyApp()); // アプリをスタートさせる
}

class MyApp extends StatelessWidget {
  const MyApp({super.key}); // アプリの設計図を作るクラス。基本的に動かない内容を持つ

  @override
  Widget build(BuildContext context) {
    // アプリの見た目を作る
    return MaterialApp(
      title: 'Flutter Demo', // アプリの名前
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), // アプリの色テーマを設定（今回は紫色）
        useMaterial3: true, // Material3デザインを使います
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'), // 最初に表示するページを設定
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title}); // 動くページを作ります

  final String title; // ページのタイトルを保持

  @override
  State<MyHomePage> createState() => _MyHomePageState(); // ページの動きを決める部分を作成
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0; // 数字（カウンター）を保持する変数、最初は0

  void _incrementCounter() {
    // カウンターを増やすための関数
    setState(() {
      // 画面を新しくして変更を反映させる
      _counter++; // カウンターを1増やす
    });
  }

  @override
  Widget build(BuildContext context) {
    // ページ全体の見た目を作る
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary, // バーの色を設定
        title: Text(widget.title), // バーのタイトルを表示
      ),
      body: Center(
        // 中央に配置する部分を作る
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center, // 縦に真ん中に配置
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:', // 「あなたはボタンをこんなに押しました」というメッセージ
            ),
            Text(
              '$_counter', // カウンターの現在の値を表示
              style: Theme.of(context).textTheme.headlineMedium, // テキストのスタイルを設定
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter, // ボタンが押されたらカウンターを増やす
        tooltip: 'Increment', // ボタンにカーソルを合わせたときのメッセージ
        child: const Icon(Icons.add), // ボタンの見た目は「+」のマーク
      ),
    );
  }
}
```
次回はじゃんけんアプリについて見ていきましょう。
https://qiita.com/jin112343/items/fe69b9fdf22fccbb6dec