今回は、保存済みの試合データに対して一括で削除を行う機能を追加しました。この機能により、複数の試合データを簡単に選択して、一度に削除できるようになります。
主な機能
- 試合データの一括削除: チェックボックスで複数の試合データを選択し、一括で削除が可能。
- 確認ダイアログ: 削除時には確認用のダイアログが表示されるため、誤って削除することを防止します。
実装の背景
試合データの管理が煩雑になってきたため、複数の試合を一度に削除できる機能が求められていました。この機能によって、ユーザーは必要なデータのみを素早く残すことができるようになり、操作性が向上します。
実装内容
チェックボックスの追加
各試合データの横にチェックボックスを追加し、複数選択ができるようにしました。これにより、不要な試合データを一括して選択可能です。
一括削除ボタン
画面右上に削除アイコンを配置し、チェックボックスで選択されたデータを一括削除することができます。
実際のコード
以下は、この機能を実装したコードです。
import 'package:flutter/material.dart';
import 'game_entry_provider.dart';
import 'score_input_screen.dart';
class GameDataScreen extends StatefulWidget {
@override
_GameDataScreenState createState() => _GameDataScreenState();
}
class _GameDataScreenState extends State<GameDataScreen> {
final GameEntryProvider _gameProvider = GameEntryProvider();
List<GameEntry> _games = [];
Set<int> _selectedGameIds = Set<int>(); // チェックボックスで選択されたゲームIDを格納
@override
void initState() {
super.initState();
_loadGames();
}
Future<void> _loadGames() async {
List<GameEntry> games = await _gameProvider.getAllGames();
setState(() {
_games = games;
});
}
Future<void> _deleteGame(int gameId) async {
await _gameProvider.deleteGame(gameId);
_loadGames(); // データを再読み込みしてUIを更新
}
Future<void> _deleteSelectedGames() async {
for (int gameId in _selectedGameIds) {
await _gameProvider.deleteGame(gameId);
}
_selectedGameIds.clear(); // 削除後に選択をクリア
_loadGames(); // データを再読み込みしてUIを更新
}
void _showDeleteConfirmationDialog(int? gameId) {
String contentText;
VoidCallback onConfirm;
if (gameId != null) {
contentText = "この試合データを削除しますか?";
onConfirm = () {
_deleteGame(gameId);
Navigator.of(context).pop(); // ダイアログを閉じる
};
} else {
contentText = "選択した試合データをすべて削除しますか?";
onConfirm = () {
_deleteSelectedGames();
Navigator.of(context).pop(); // ダイアログを閉じる
};
}
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("試合データの削除"),
content: Text(contentText),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(), // ダイアログを閉じる
child: Text("キャンセル"),
),
TextButton(
onPressed: onConfirm,
child: Text("削除"),
),
],
);
},
);
}
void _showEditGameDialog(GameEntry game) {
TextEditingController nameController =
TextEditingController(text: game.name);
TextEditingController venueController =
TextEditingController(text: game.venue);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("試合情報の編集"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: nameController,
decoration: InputDecoration(hintText: '試合名'),
),
TextField(
controller: venueController,
decoration: InputDecoration(hintText: '会場名'),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("キャンセル"),
),
TextButton(
onPressed: () async {
GameEntry updatedGame = GameEntry(
id: game.id,
name: nameController.text,
venue: venueController.text,
date: game.date, // 日付はそのまま
teamAId: game.teamAId, // 既存のteamAIdを保持
teamBId: game.teamBId, // 既存のteamBIdを保持
);
await _gameProvider.updateGame(updatedGame);
_loadGames();
Navigator.of(context).pop();
},
child: Text("保存"),
),
],
);
},
);
}
void _showLoadGameDialog(GameEntry game) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("試合を再開"),
content: Text("この試合を再開しますか?"),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("キャンセル"),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(); // ダイアログを閉じる
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ScoreInputScreen(gameId: game.id),
),
);
},
child: Text("再開"),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('保存済みの試合データ'),
actions: [
IconButton(
icon: Icon(Icons.delete),
onPressed: _selectedGameIds.isNotEmpty
? () => _showDeleteConfirmationDialog(null)
: null, // 選択されているデータがあれば削除ボタンを有効にする
),
],
),
body: ListView.builder(
itemCount: _games.length,
itemBuilder: (context, index) {
final game = _games[index];
final isSelected = _selectedGameIds.contains(game.id);
return ListTile(
leading: Checkbox(
value: isSelected,
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedGameIds.add(game.id!); // ゲームIDをセットに追加
} else {
_selectedGameIds.remove(game.id); // ゲームIDをセットから削除
}
});
},
),
title: Text(game.name),
subtitle: Text('会場: ${game.venue} - 日付: ${game.date}'),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit),
onPressed: () => _showEditGameDialog(game),
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () => _showDeleteConfirmationDialog(game.id),
),
],
),
onTap: () => _showLoadGameDialog(game),
);
},
),
);
}
}
コメント