バスケットボールスコア入力アプリ(ランニングスコア)にチーム登録およびメンバー登録一覧に一括削除機能を追加しました。
これまでのアプリでは、チームやメンバーを1件ずつ削除する必要があり、複数のデータを管理する際には手間がかかっていました。そこで、複数のチームやメンバーをまとめて削除できるように、チェックボックスを使った一括削除機能を実装しました。
機能の概要
この機能では、チーム登録画面やメンバー登録画面において、一覧表示されたデータの左側にチェックボックスを追加しました。ユーザーが削除したい項目にチェックを入れ、画面上部のゴミ箱アイコンをクリックすることで、選択された項目を一括で削除することができます。
削除実行時には確認ダイアログが表示され、ユーザーに本当に削除してよいかの確認が求められます。「はい」を選択すると、選択したすべてのデータが一度に削除されます。
実装の詳細
チーム登録画面のコード例
まず、チーム登録画面の一覧に対してチェックボックスを追加し、一括削除機能を実装した部分を紹介します。
import 'package:flutter/material.dart';
import 'team_provider.dart';
import 'member_registration_screen.dart';
class TeamRegistrationScreen extends StatefulWidget {
@override
_TeamRegistrationScreenState createState() => _TeamRegistrationScreenState();
}
class _TeamRegistrationScreenState extends State<TeamRegistrationScreen> {
final TeamProvider _teamProvider = TeamProvider();
List<Team> _teams = [];
Set<int> _selectedTeamIds = Set<int>(); // 一括削除のための選択セット
@override
void initState() {
super.initState();
_loadTeams();
}
Future<void> _loadTeams() async {
List<Team> teams = await _teamProvider.getAllTeams();
setState(() {
_teams = teams;
});
}
Future<void> _deleteSelectedTeams() async {
for (int teamId in _selectedTeamIds) {
await _teamProvider.deleteTeam(teamId);
}
_loadTeams();
_selectedTeamIds.clear(); // 削除後、選択をクリア
}
// 一括削除確認ダイアログ
void _showDeleteConfirmationDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("チーム削除"),
content: Text("選択されたチームをすべて削除しますか?"),
actions: [
TextButton(
onPressed: () async {
await _deleteSelectedTeams(); // 一括削除を実行
Navigator.of(context).pop();
},
child: Text("はい"),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("いいえ"),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('チーム登録'),
actions: [
IconButton(
icon: Icon(Icons.delete),
onPressed: _selectedTeamIds.isNotEmpty
? _showDeleteConfirmationDialog
: null, // チェックされていない場合は無効化
),
IconButton(
icon: Icon(Icons.add),
onPressed: () => _addOrEditTeam(),
),
],
),
body: _teams.isEmpty
? Center(child: Text('保存されたチームはありません'))
: ListView.builder(
itemCount: _teams.length,
itemBuilder: (context, index) {
final team = _teams[index];
final isSelected = _selectedTeamIds.contains(team.id);
return ListTile(
leading: Checkbox(
value: isSelected,
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedTeamIds.add(team.id!);
} else {
_selectedTeamIds.remove(team.id);
}
});
},
),
title: Text(team.name),
subtitle: Text('${team.location} - 順位: ${team.displayOrder}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
MemberRegistrationScreen(team: team),
),
);
},
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit),
onPressed: () => _addOrEditTeam(team: team),
),
],
),
);
},
),
);
}
}
メンバー登録画面でも同様の実装
メンバー登録画面でも同様の実装を行いました。チェックボックスを追加し、選択されたメンバーを一括で削除できるようにしています。
import 'package:flutter/material.dart';
import 'member_provider.dart';
import 'team_provider.dart';
class MemberRegistrationScreen extends StatefulWidget {
final Team team;
MemberRegistrationScreen({required this.team});
@override
_MemberRegistrationScreenState createState() =>
_MemberRegistrationScreenState();
}
class _MemberRegistrationScreenState extends State<MemberRegistrationScreen> {
final MemberProvider _memberProvider = MemberProvider();
List<Member> _members = [];
Set<int> _selectedMemberIds = Set<int>(); // 一括削除のための選択セット
@override
void initState() {
super.initState();
_loadMembers();
}
Future<void> _loadMembers() async {
List<Member> members =
await _memberProvider.getMembersByTeamId(widget.team.id!);
setState(() {
_members = members;
});
}
Future<void> _deleteSelectedMembers() async {
for (int memberId in _selectedMemberIds) {
await _memberProvider.deleteMember(memberId);
}
_loadMembers();
_selectedMemberIds.clear();
}
// 一括削除確認ダイアログ
void _showDeleteConfirmationDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("メンバー削除"),
content: Text("選択されたメンバーをすべて削除しますか?"),
actions: [
TextButton(
onPressed: () async {
await _deleteSelectedMembers(); // 一括削除を実行
Navigator.of(context).pop();
},
child: Text("はい"),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("いいえ"),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${widget.team.name} メンバー登録'),
actions: [
IconButton(
icon: Icon(Icons.delete),
onPressed: _selectedMemberIds.isNotEmpty
? _showDeleteConfirmationDialog
: null,
),
IconButton(
icon: Icon(Icons.add),
onPressed: () => _addOrEditMember(),
),
],
),
body: _members.isEmpty
? Center(child: Text('保存されたメンバーはありません'))
: ListView.builder(
itemCount: _members.length,
itemBuilder: (context, index) {
final member = _members[index];
final isSelected = _selectedMemberIds.contains(member.id);
return ListTile(
leading: Checkbox(
value: isSelected,
onChanged: (bool? value) {
setState(() {
if (value == true) {
_selectedMemberIds.add(member.id!);
} else {
_selectedMemberIds.remove(member.id);
}
});
},
),
title: Text(member.name),
subtitle: Text('番号: ${member.number}, ポジション: ${member.position}'),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit),
onPressed: () => _addOrEditMember(member: member),
),
],
),
);
},
),
);
}
}
コメント