Flutter備忘録

# はじめに
今回、Flutterでとあるアプリを開発していきたいのでそれらの備忘録をこちらにまとめていきます。

:::note warn
警告
あくまで備忘録のサンプルコードなので実行は自己責任でお願いします。
:::

サンプルコードはWebベースでも走らせることができその際に前回でも利用した
Dartpadが便利なのでぜひご利用しながら試してみてください

https://dartpad.dev/?sample=counter

Flutterをする上でDartに関する知識が必要になってきますのでその基礎などをまとめているのでぜひこちらもご覧下さい

https://qiita.com/nanashi39/items/0a7a65feeaaecec9b56d


また非常に有意義な資料がこちらにもあるので参考にしてみてください

https://www.flutter-study.dev/


# アプリ開発における基礎知識

## ウィジェット(widget)
アプリケーションを開発していくにあたってよく「**ウィジェット**」という言葉を耳にします。

**<a href="https://developer.android.com/develop/ui/views/appwidgets/overview?hl=ja#:~:text=%E3%82%A6%E3%82%A3%E3%82%B8%E3%82%A7%E3%83%83%E3%83%88%E3%81%AF%E3%80%81%E3%83%9B%E3%83%BC%E3%83%A0%E7%94%BB%E9%9D%A2%E3%81%AE,%E3%82%A6%E3%82%A3%E3%82%B8%E3%82%A7%E3%83%83%E3%83%88%E3%82%92%E7%A7%BB%E5%8B%95%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82">ウィジェット</a>**
>アプリの特に重要なデータや機能を「ひと目で」確認できるようにし、そうしたデータや機能にユーザーのホーム画面から直接アクセスできるようにするもの

上記のような解説でAndroid Studio公式さんは言ってます(詳しくはリンク参照で)
画面に表示されているUIの部品だと考えてもらってもいいっぽい

---

## Stateless(ステートレス)とStateful(ステートフル)

**Stateless** → 初期化などしたら基本的に **変更**がないもの
 * 使いどころ：静的なUIなどの部分(基本一度定義されたら変更のないもの)
 * 例: ボタンの色や固定された背景色など


**Stateful**　→ 変更などを **動的に** 管理できるもの
 * 使いどころ：ユーザーなどの動作によって **変化**があるところ
 * 例 : カウンターやユーザーの情報など

大きな違いとして「**状態の変化**」があるか無いか
# 本編
## 開発環境
今回使用している開発環境
OS：Windows11 Pro 
IDE：VScode
Flutterバージョン：3.24.5
エミュレーター：Pixel 9 Pro XL API
## ウィジェット各種について

### **表示についての基礎**
今回はサンプル画面このようなサンプル画面を表示されるようなものを作るとします。
(文章はGPT大先生より)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/26502fe6-dfd5-b8ee-6f5c-090b139c3194.png" alt="Android" width="200" />

簡単にこれでやっていることの説明

 * サンプルプログラムを削除して、アプリのど真ん中に長い文章を6行で表示させるようにしている。

**ここで使用しているウィジェット**
- CenterWidget
- ChildWidget
- TextWidget
- TextStyleWidget

ウィジェットはある程度メソッドと考えてもOK
イメージとしては **引数として** 要素を受け渡していっている
それらが **一つになり一つの画面** を生み出している。

---
**ウィジット説明**
 **``CenterWidget``**　→　中央に配置するものを定義
 **``ChildWidget``**　 → センターの子ウィジェットにとなりそこに要素を入れる
 **``TextWidget``** 　→ テキストを配置するためのウィジェット
**``TextStyleWidget``** 　→　テキストの大きさなどを指定
 引数として **``maxLines(何行で表示するか)``** を6行にして
  **``overflow``** もし文字列が横幅を越したとき **``ellipis(訳：省略)``**　として「...」を表示する。
また、フォントの色を黒色,大きさを16と定義している。

 <details><summary><strong>コード例</strong></summary>
 
```main.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 
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: const Center(
        child: Text(
          'Flutterは、Googleが提供するモバイルアプリケーションフレームワークであり、単一のコードベースからAndroidおよびiOS用の高品質なアプリを構築できます。このテキストは長い文章の例として追加していますが、maxLinesプロパティによって行数が制限され、overflowプロパティで適切に処理されます。',
          maxLines: 6,  // 6行に設定
          overflow: TextOverflow.ellipsis, // 3点リーダーで省略
          style: TextStyle(
            fontSize: 16, // フォントサイズ
            color: Colors.black, // テキストの色
          ),// textStyle
        ), // child
      ), // center
    ); // Scaffold 
  } // build
} // class

```
</details>


上記の例のように色々ととウィジットによって管理でき,カスタマイズできるので皆さんも調べて試してみてください～


他詳細は以下の資料を見てください

https://www.flutter-study.dev/widgets/text-widget


<details><summary><strong> Containerで遊んでみる(興味ある方のみどうぞ笑)</strong></summary>

Containerウィジェットを利用することによって色々と表示で遊べます(下記のリンク参照)

https://api.flutter.dev/flutter/widgets/Container-class.html

ここに乗っているサンプルをもとにサンプルを上げて遊んでみたいと思います。（遊び心大事)

例**長方形の中にテキストを入れ込む(コンテナーで体裁管理)**

実際のエミュレーターの画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/009e46c6-b280-d345-06e5-3684125e0f6d.png
" width="200" />

**コード例**
```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      // アプリのボディ部分
      body: Center( // 真ん中に
        child: Container( // コンテナーとして
          padding: const EdgeInsets.all(20), // 余白を追加
          decoration: BoxDecoration(
            shape: BoxShape.rectangle, // 長方形を指定
            borderRadius: BorderRadius.circular(12), // 角を丸くする
            color: Colors.blue, // 背景色
          ),
          child: const Text( // コンテナーの子ウィジェットとしてテキスト定義
            "コンテナーで遊ぼう",
            style: TextStyle(
              color: Colors.white, // テキストの色
              fontSize: 18, // フォントサイズ
            ),
          ),
        ),
      ),
    );
  }
}
```

こんな感じで表示を遊ぶこともできます。
楽しくなってきたでしょう。

</details>

## 画像表示系
### image.networkウィジェット
**画像のリンクからアプリに表示させることができるもである。**
今回はとても美味しかった、骨付き肉を堂々と画面中央に表示したいと思います。

今回作成するもののイメージ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/5544ce10-51c7-f2e2-984a-a75145cbc7a4.png
" width="200" />


以下元画像(これ実は羊肉です笑)
ご自由にお使いください

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/ff9dc245-ae03-5537-0b2d-9c83fc2b8053.png" width="500" />

---
それでは気を取り直して
**``Image.network``**　について

このウィジェットでは引数として以下のものを設定できます(一部抜粋)
-  **``src``** → 画像のアドレスを指定(リンク)
-  **``width / height``** →　``double型``で認識されて縦幅、横幅を指定できる
-  **``fit``** →　アスペクト比(縦横比)を変えてもはみ出さないようにする(親ウィジェット内で表示する)ための引数

<details><summary><strong> コード例</strong></summary>

```mian.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Image.network(
          'https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/ff9dc245-ae03-5537-0b2d-9c83fc2b8053.png',
          width: 300, // 画像の幅を指定
          height: 250, // 画像の高さを指定
          fit: BoxFit.cover, // 親要素に合わせて表示
        ),
      ),
    );
  }
}


```

</details>
imgage.networkウィジェットはここまでです。

(ChatGPTに聞いたら画像ロードを判定させてロードのUIを表示させるとかできるらしい)

---

### Image.assetウィジェット

今回のウィジェットはローカルファイルから画像を表示するウィジェットです。

今回は画像を変えてこれをローカルファイルから参照して画面中央に堂々と表示するようにしてみる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/3a89f55e-4e8f-4b24-62da-ca9d0c79f831.jpeg" width="500"/>


今回期待する画面
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/40e44fc3-7841-f371-5b20-6adf897ba90b.png
" width="200" />

--- 
#### **やり方**
①プロジェクトフォルダの中にassets(任意で可能)フォルダを作成して画像を入れる

② **pubspec.yaml** にパスを通す
プロジェクトフォルダの一番上の階層に入っています。

**pubspec.yaml**に設定を記述していきます。
```pubsepec.yaml
# To add assets to your application, add an assets section, like this:
  assets: # 最初ここはコメントになっている
  # 相対パスを記述
  - assets/S__53043236.jpg # ここは自分で記述
  # - images/a_dot_burr.jpeg
  # - images/a_dot_ham.jpeg

```
**コメントでも書いてますが「assets」はコメントになっておりコメントを外してあげて相対パスを記述してあげることにより使用できるようになります。**

③実際にウィジェットを利用してみる

<details><summary><strong>コード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Image.asset(
          'assets/S__53043236.jpg',
          width: 300, // 画像の幅を指定
          height: 250, // 画像の高さを指定
          fit: BoxFit.cover, // 親要素に合わせて表示
        ),
      ),
    );
  }
}

```

</details>

これで画像表示系は終わりです。


## Paddingウィジェット
子ウィジェットにPadding(余白)を追加するウィジェットです。
子としてTextを持ちます

###  画面遷移イメージ

以下は、2つの画面を横並びに表示し、遷移の流れを示したものです。

|変更前 | 変更後 |
|------------|----------|
| ![現在の画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/b175e61e-9e83-add6-28d0-4f50fd8bbd8d.png) | ![次の画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/d65a57a2-f4f1-f8e7-a06d-ab247000da81.png) |

このようにして子ウィジェットにあたる「 **Text** 」に余白を持たせることのウェイジェットになっています。
<details><summary><strong>実際のコード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Container(
        color: Colors.green,
        child: Padding(
          padding: const EdgeInsets.all(24.0), // パディングを追加
          child: const Text(
            "なんか色々と長めの文章を書いてみます。文章力がないのでなかなか文章が思いつかないですが頑張って文字書いてます。最近、美味しいシュークリーム屋さんを発見してテンションが結構上がってます。やったねー！",
            style: TextStyle(
              color: Colors.white, // 文字色を白に設定
              fontSize: 16, // フォントサイズを設定
            ),
          ),
        ),
      ),
    );
  }
}
```
</details>


###   paddingウィジェットの引数設定について(ChatGPTより)

引数呼び出しの際は名前付き引数となっており,明示的に引き渡す引数名を書く必要がある。
また、引数を一つだけでも指定は可能。
 
| メソッド          | 説明                                                                                   | 使用例                             |
|-------------------|----------------------------------------------------------------------------------------|-----------------------------------|
| `EdgeInsets.all`  | 全方向（上下左右）に同じ余白を設定する                                             | `EdgeInsets.all(8.0)`             |
| `EdgeInsets.only` | 特定の方向（`left`, `top`, `right`, `bottom`）に余白を設定する                      | `EdgeInsets.only(left: 8.0)`      |
| `EdgeInsets.symmetric` | 水平方向（`horizontal`）または垂直方向（`vertical`）に均等な余白を設定する        | `EdgeInsets.symmetric(horizontal: 16.0)` |
| `EdgeInsets.fromLTRB` | 左（`left`）、上（`top`）、右（`right`）、下（`bottom`）の4方向それぞれに余白を設定する。 | `EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 16.0)` |

## ColoredBoxウィジェット

指定したウィジェットの範囲をカラーボックスで囲むことのできるウィジェット

こんな感じで表示できるようになる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/5e17cb3c-0dcc-922b-23e8-147479aab03b.png
" width="200" />

ちなにみPaddingウィジェットの子要素としても埋め込める

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/39ff9e16-74f7-f768-5574-32094b0cec30.png"
 width="200" />

こんな感じで色々と遊べます。

<details><summary><strong>コード例(Paddingを含んだバージョン)</strong>
</summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ColoredBox(
        color: Colors.red, 
        child: Padding(

          padding: EdgeInsets.all(20),
          child: const Text(
            "テスト的な文章",
            style: TextStyle(
              color: Colors.white, 
              fontSize: 20, 
            ) // Padding  
          ),//TextStyle
        ), // Text
      ), // ColoredBox
    );
  }
}
```
</details>

### 色などの設定で使えるメソッド(Colorクラスのメソッド)


| メソッド名                | 説明                                                                 |
|---------------------------|----------------------------------------------------------------------|
| `fromARGB(int a, int r, int g, int b)` | ARGB（アルファ、赤、緑、青）で色を生成します。`a` は透明度、`r` は赤、`g` は緑、`b` は青の設定ができる |
| `withOpacity(double opacity)` | 色の不透明度を変更した新しい色を返します。`opacity` は 0.0 から 1.0 の範囲で指定できる。      |
| `computeLuminance()`          | 色の明るさ（輝度）を計算し、0.0（暗い）から 1.0（明るい）の範囲で返す              |
| `toString()`                 | 色を文字列として返す   

となっており、今回のColorBoxのcolor引数として上記のメソッドを渡してやると自由に変えることができる。

## Alignウィジェット

上下左右の配置を設定できるウィジェット

場所の指定するテンプレ
```main.dart
Align(
    alignment: Alignment.// 指定する設定
    child: Text("テキスト")
```
こんな書き方をする
設定できるものとして以下のようなものがある

| メソッド/プロパティ         | 説明                                    |
|-------------------------|---------------------------------------|
| `Alignment.topLeft`      | ウィジェットを左上に配置する。                   |
| `Alignment.topCenter`    | ウィジェットを上中央に配置する。                 |
| `Alignment.topRight`     | ウィジェットを右上に配置する。                   |
| `Alignment.centerLeft`   | ウィジェットを中央左に配置する。                 |
| `Alignment.center`       | ウィジェットを完全に中央に配置する。              |
| `Alignment.centerRight`  | ウィジェットを中央右に配置する。                 |
| `Alignment.bottomLeft`   | ウィジェットを左下に配置する。                   |
| `Alignment.bottomCenter` | ウィジェットを下中央に配置する。                 |
| `Alignment.bottomRight`  | ウィジェットを右下に配置する。                   |
| `Alignment(x, y)`        | ウィジェットを指定した位置に配置する。`x`と`y`は-1.0から1.0の範囲で、-1.0は左や上、1.0は右や下を意味する。 |

使用例（画像)
今回はtopCenterメソッド利用してみた
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/0846cead-1b0d-e204-da98-154ad9c35a1a.png
" width="200" />

<details><summary><strong>コード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Align(
        alignment: Alignment.topCenter,
        child: Text(
          "テスト的な文章"
        ),
      ),
    );
  }
}
```

</details>

## ボタン系ウィジェット
### Textbuttonウィジェット
画面にボタンを追加するウィジェット

 **基本文法**
 ```dart
 TextButton(
     // ボタンが押されたとき
     onPressed:(){
     // ここに処理を記述
     
     },
     // ボタン押されていないとき
     child: // 任意のウィジェット
 )
 ```
今回、出力する画面例はこちらです

ボタンが押されたらコンソールに「もう来ないからね～」
と表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/4dd85bf9-9155-a6f7-160a-c5f4724ed8e4.png
" width="400" />

<details><summary><strong>コード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            // ボタンが押されたときの処理を記述
            print("もう来ないからね～");
          },
          child: const Text("ボタン押してね～"),
        ),
      ),
    );
  }
}

```

</details>

### Elevatedbuttonウィジェット
同じボタン系のウィジェットであるが立体的に結構わかりやすく視覚的にボタンを追加できる

**画面出力例**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/0285cb42-4bcb-92ce-9769-66abd646678d.png" width = "400" />

<details><summary><strong>コード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor:
                const Color.fromARGB(255, 17, 244, 17), // ボタンの背景色を濃く設定
          ),
          onPressed: () {
            // ボタンが押されたときの処理
            print("もう来ないからね～");
          },
          child: const Text("ボタン押してね～"),
        ),
      ),
    );
  }
}

```

ボタンの丸みを調整できるためのウィジェットもあり

```main.dart
child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              backgroundColor:
                  // ボタンの背景色指定
                  const Color.fromARGB(255, 17, 244, 17), // ボタンの背景色を濃く設定
              // 角をどれだけ丸にするかの設定
              shape: RoundedRectangleBorder( 
                  borderRadius: BorderRadius.circular(8)
                  ) // RoundedRectangleBorder
                ), // style
            // ...続く
    
```

のようにするとボタンの丸みを調整できる

**完全な丸にするとき**
```dart
 style: ElevatedButton.styleFrom(
            backgroundColor: const Color.fromARGB(255, 17, 244, 17), // 背景色
            shape: const CircleBorder(), // 角を丸く設定
            padding: const EdgeInsets.all(70), // パディング
          ),
```

</details>

### OutlineButtoneウィジェットについて

これもボタンの一種です
これもほぼ同じなので詳細は割愛します

Centerの子ウィジェットにOutlineButtonと書くだけで他同じです

**画面出力だけを提示しておきます**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/b2191ba9-45e5-7aca-2bec-43e2596287d3.png
" width = "400" />




## AlrtDialogウィジェット

ダイアログを表示するウィジェットで大体なにかの処理の後なので
「 **showDialog関数** 」で呼び出すようにする

このウィジェットは3つの構成要素を持ち

title　→　ダイアログ表示時のタイトル
content →　ダイアログ内で行処理などのウィジェット
action →　ダイアログが表示されたあとどのような動作でなにをするか

**基本文法**
```dart
showDialog(context: context,builder: (context){
return AlertDialog(
    title:    // ダイアログのタイトル
    content:  // ダイアログ内の内容
    action:   //ダイアログ内の処理
);    
```
**画面例(TextButtonウィジェットと組み合わせてます)**

| ボタン押下前 | ボタン押下後 |
|--------|--------|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/9baff51e-b8a3-e28e-f0a9-a2f8d67f9e71.png" width="300"/> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628177/a7ce5cc4-84ac-b995-52cc-316661d24b89.png" width="300"/> |




<details><summary><strong>コード例</strong></summary>

```main.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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            // ボタンが押されたときの処理を記述

            print("もう来ないからね～");
            showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: Text("○っち"),
                    content: Text("もう来ないからね～"),
                    actions: [
                      TextButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text("close"))
                    ],
                  );
                });
          },
          child: const Text("ボタン押してね～"),
        ),
      ),
    );
  }
}

```

</details>



# 最後に
あまり綺麗ではない備忘録を最後までご閲覧いただきありがとうございました。

備忘録なのでどんどん更新していくと思いますのでご期待ください。

ご指摘や「これいいよ！」とかあればぜひコメントいただけると嬉しいです。

僕みたいな初学者の方の足しに少しでもなればいいと思います。


# 参考にさせていただいた記事,資料など

https://www.udemy.com/course/nzigen-flutter_beginner/?couponCode=BFCPSALE24JP

https://minpro.net/boxfit-cover-boxfit-fill