Flutterのチュートリアルを学んでみた(14)

# StatefulWidgetで動きのあるアプリを作ろう！ 🎮

## StatefulWidgetって何？ 🤔

SNSの「いいね」ボタンのように、タップすると状態が変わる機能を作りたいことありませんか？
そんなときに使うのが`StatefulWidget`です！

簡単に言うと：
- 👉 押すと変化する
- 💾 値を覚えておける
- 🔄 画面を更新できる

## 基本の作り方 📝

### Step 1: StatefulWidgetを作る
```dart
class ClickGood extends StatefulWidget {
  @override
  _ClickGoodState createState() => _ClickGoodState();
}
```
これは「状態を持てる部品を作るよ」という宣言です！

### Step 2: Stateを作る
```dart
class _ClickGoodState extends State<ClickGood> {
  // ここに状態を保存する変数を書きます
  bool _active = false;  // 初期値はfalse

  @override
  Widget build(BuildContext context) {
    return Container();  // ここに見た目を書きます
  }
}
```

## 値を変更する方法 🔄

### Step 3: 変更用の関数を作る
```dart
void _handleTap() {
  setState(() {    // これが大事！
    _active = !_active;  // trueとfalseを切り替える
  });
}
```

重要ポイント：
- 値を変えるときは必ず`setState`の中で！
- `setState`を使うと自動で画面が更新される

## 実践例：いいねボタン 👍

完成形はこんな感じ：
```dart
class LikeButton extends StatefulWidget {
  @override
  _LikeButtonState createState() => _LikeButtonState();
}

class _LikeButtonState extends State<LikeButton> {
  bool _isLiked = false;  // いいねの状態

  void _toggleLike() {
    setState(() {
      _isLiked = !_isLiked;  // 状態を反転
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _toggleLike,  // タップされたら_toggleLikeを実行
      child: Icon(
        Icons.favorite,
        color: _isLiked ? Colors.red : Colors.grey,  // いいね状態で色変更
        size: 30,
      ),
    );
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/0a1aed13-d518-6e23-248f-e1c5a9190305.png)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929117/0c89fed2-33ea-cf6f-2330-a6ebaad97a60.jpeg" width="330" height="330">

## やってみよう！ 💪

1. シンプルなカウンター
```dart
class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;  // カウント用の変数

  void _increment() {
    setState(() {
      _count++;  // カウントを増やす
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          '$_count',
          style: TextStyle(fontSize: 40),
        ),
        ElevatedButton(
          onPressed: _increment,
          child: Text('増やす'),
        ),
      ],
    );
  }
}
```

2. ON/OFFスイッチ
```dart
class ToggleSwitch extends StatefulWidget {
  @override
  _ToggleSwitchState createState() => _ToggleSwitchState();
}

class _ToggleSwitchState extends State<ToggleSwitch> {
  bool _isOn = false;

  @override
  Widget build(BuildContext context) {
    return Switch(
      value: _isOn,
      onChanged: (bool value) {
        setState(() {
          _isOn = value;
        });
      },
    );
  }
}
```

## 困ったときは？ 🆘

- 値が変わらない
  → setStateを使っているか確認
- 画面が更新されない
  → 変数の変更がsetStateの中にあるか確認
- エラーが出る
  → Stateクラスの名前が合っているか確認

## 大切なポイント ⭐️

1. StatefulWidgetとStateは必ずセット
2. 値を変えるときは必ずsetState
3. プライベート変数は_（アンダースコア）をつける
4. buildメソッドで見た目を作る

## チャレンジ！ 🎯

1. いいねボタンに数字を追加してみよう
2. ダークモード切り替えボタンを作ってみよう
3. お気に入り登録機能を作ってみよう

## 応用例：ショッピングカート 🛒

```dart
class ShoppingCart extends StatefulWidget {
  @override
  _ShoppingCartState createState() => _ShoppingCartState();
}

class _ShoppingCartState extends State<ShoppingCart> {
  int _itemCount = 0;
  
  void _addItem() {
    setState(() {
      _itemCount++;
    });
  }

  void _removeItem() {
    setState(() {
      if (_itemCount > 0) _itemCount--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        IconButton(
          icon: Icon(Icons.remove),
          onPressed: _removeItem,
        ),
        Text(
          '$_itemCount',
          style: TextStyle(fontSize: 20),
        ),
        IconButton(
          icon: Icon(Icons.add),
          onPressed: _addItem,
        ),
      ],
    );
  }
}
```

StatefulWidgetをマスターすれば、
もっとインタラクティブな素敵なアプリが作れます