Flutterバスケアプリ | プレイ内容の編集機能を追加

今回は、バスケットボールスコア入力アプリ(ランニングスコア)にプレイ内容の編集機能を実装しました。これまでは削除しか出来ませんでしたが、選手番号や内容の変更が出来るようになります。

プレイ内容の編集機能

1. プレイ内容の編集機能とは?

プレイ内容の編集機能では、以下の項目を編集することが可能です。

  • チームの変更
    間違ったチームでプレイを記録してしまった場合、正しいチームを選び直すことができます。
  • プレイヤー番号の変更
    選手の番号を間違えて入力してしまった場合、正しい番号に修正することができます。
  • プレイの種類の変更
    “FT”(フリースロー)、”2P”(2ポイント)、”3P”(3ポイント)、”ファウル”、”タイムアウト”の各プレイ種類も修正できます。

2. 使い方の概要

プレイ一覧から編集
スコア入力画面の「プレイ内容一覧」から、編集したいプレイの横にある「編集」アイコンをタップします。すると、プレイ内容を編集できるダイアログが表示されます。このダイアログでは、チーム、プレイヤー番号、プレイ種類を選択して、修正後に「保存」ボタンを押すだけで簡単にプレイを更新することができます。

削除機能も強化
編集機能と併せて、プレイの削除機能も強化しました。削除アイコンをタップすると確認ダイアログが表示され、誤って削除してしまうことを防ぎます。

3. 改善されたユーザー体験

今回のアップデートにより、試合中に誤って入力したプレイデータを後から修正できるため、スコア入力作業が一層スムーズになりました。ミスを気にせず、リアルタイムに試合の状況を記録できるので、より正確なスコア管理が実現できます。

4. 該当コード

Future<void> _showEditPlayDialog(PlayEntry play) async {
  int? selectedPlayerNumber = int.tryParse(play.playerNumber);
  String selectedPlayType = play.playType;
  int? selectedTeamId = play.teamId;
  List<int> availablePlayerNumbers = [];

  if (selectedTeamId != null) {
    availablePlayerNumbers = _members
        .where((member) => member.teamId == selectedTeamId)
        .map((member) => member.number)
        .toList();
  }

  await showDialog<void>(
    context: context,
    builder: (BuildContext context) {
      return StatefulBuilder(
        builder: (context, setState) {
          return AlertDialog(
            title: Text('プレイ内容の編集'),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                DropdownButtonFormField<int>(
                  decoration: InputDecoration(hintText: 'チームを選択'),
                  value: selectedTeamId,
                  items: [_selectedTeamAId, _selectedTeamBId]
                      .where((id) => id != null)
                      .map((id) {
                    final team = _teams.firstWhere((team) => team.id == id);
                    return DropdownMenuItem<int>(
                      value: team.id,
                      child: Text(team.name),
                    );
                  }).toList(),
                  onChanged: (value) {
                    setState(() {
                      selectedTeamId = value;
                      availablePlayerNumbers = _members
                          .where((member) => member.teamId == selectedTeamId)
                          .map((member) => member.number)
                          .toList();
                      availablePlayerNumbers.add(999);
                      selectedPlayerNumber = null;
                    });
                  },
                ),
                DropdownButtonFormField<int>(
                  decoration: InputDecoration(hintText: 'プレイヤー番号を選択'),
                  value: selectedPlayerNumber,
                  items: availablePlayerNumbers.map((number) {
                    return DropdownMenuItem<int>(
                      value: number,
                      child: Text(number == 999 ? 'TEAM' : '$number'),
                    );
                  }).toList(),
                  onChanged: (value) {
                    setState(() {
                      selectedPlayerNumber = value;
                    });
                  },
                ),
                DropdownButtonFormField<String>(
                  decoration: InputDecoration(hintText: 'プレイ内容を選択'),
                  value: selectedPlayType,
                  items: ['FT', '2P', '3P', 'ファウル', 'タイムアウト'].map((type) {
                    return DropdownMenuItem<String>(
                      value: type,
                      child: Text(type),
                    );
                  }).toList(),
                  onChanged: (value) {
                    setState(() {
                      selectedPlayType = value!;
                    });
                  },
                ),
              ],
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: Text('キャンセル'),
              ),
              TextButton(
                onPressed: () async {
                  PlayEntry updatedPlay = PlayEntry(
                    id: play.id,
                    teamId: selectedTeamId!,
                    points: play.points,
                    quarter: play.quarter,
                    playType: selectedPlayType,
                    time: play.time,
                    playerNumber: selectedPlayerNumber?.toString() ?? '0',
                    gameId: play.gameId,
                  );
                  await _playProvider.updatePlay(updatedPlay);
                  _loadPlaysForCurrentGame();
                  Navigator.of(context).pop();
                },
                child: Text('保存'),
              ),
            ],
          );
        },
      );
    },
  );
}

5. スクリーンショット

以下は、プレイ内容編集機能のスクリーンショットです。

関連記事

コメント

タイトルとURLをコピーしました