multiple selection of listitems
This commit is contained in:
@@ -5,6 +5,8 @@ import 'package:briessenchecker/services/dbhelper.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../widgets/item_list_tile.dart';
|
||||||
|
|
||||||
class DetailChecklistPage extends StatefulWidget {
|
class DetailChecklistPage extends StatefulWidget {
|
||||||
const DetailChecklistPage({super.key});
|
const DetailChecklistPage({super.key});
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
List<Item> _items = [];
|
List<Item> _items = [];
|
||||||
int? _selectedItemId;
|
int? _selectedItemId;
|
||||||
String? pageTitle;
|
String? pageTitle;
|
||||||
|
List<int> selectedItems = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@@ -108,11 +111,6 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
if (_selectedItemId != null)
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => DbHelper.deleteItemById(_selectedItemId!),
|
|
||||||
child: const Text('delete'),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_itemSaved(titleCon.text, descCon.text);
|
_itemSaved(titleCon.text, descCon.text);
|
||||||
@@ -138,6 +136,12 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(pageTitle ?? ''),
|
title: Text(pageTitle ?? ''),
|
||||||
|
actions: [
|
||||||
|
if (selectedItems.isNotEmpty)
|
||||||
|
IconButton(
|
||||||
|
onPressed: _onDeleteItemsPressed,
|
||||||
|
icon: const Icon(Icons.delete))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: FutureBuilder(
|
body: FutureBuilder(
|
||||||
future: _checklistFutures,
|
future: _checklistFutures,
|
||||||
@@ -151,10 +155,13 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget? _itemListBuilder(BuildContext context, int index) {
|
Widget? _itemListBuilder(BuildContext context, int index) {
|
||||||
return ListTile(
|
return ItemListTile(
|
||||||
title: Text(_items.elementAt(index).title),
|
title: _items.elementAt(index).title,
|
||||||
subtitle: Text(_items.elementAt(index).description),
|
description: _items.elementAt(index).description,
|
||||||
onTap: () => _itemTapped(index),
|
onTap: () => _itemTapped(index),
|
||||||
|
itemSelectionChanged: (isSelected) =>
|
||||||
|
_itemSelectionChanged(isSelected, index),
|
||||||
|
selectionMode: selectedItems.isNotEmpty,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,4 +171,18 @@ class _DetailChecklistPageState extends State<DetailChecklistPage> {
|
|||||||
DbHelper.getItemsByChecklistId(checklistId),
|
DbHelper.getItemsByChecklistId(checklistId),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _itemSelectionChanged(bool isSelected, int index) {
|
||||||
|
if (isSelected) {
|
||||||
|
setState(() {
|
||||||
|
selectedItems.add(index);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
selectedItems.remove(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDeleteItemsPressed() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
import '../models/checklist.dart';
|
import '../models/checklist.dart';
|
||||||
@@ -93,7 +94,9 @@ class DbHelper {
|
|||||||
}
|
}
|
||||||
await _client.from(itemsTableName).upsert(upsertMap);
|
await _client.from(itemsTableName).upsert(upsertMap);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
if (kDebugMode) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
50
lib/widgets/item_list_tile.dart
Normal file
50
lib/widgets/item_list_tile.dart
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
typedef BoolCallback = void Function(bool isSelected);
|
||||||
|
|
||||||
|
class ItemListTile extends StatefulWidget {
|
||||||
|
const ItemListTile({
|
||||||
|
super.key,
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.onTap,
|
||||||
|
required this.itemSelectionChanged,
|
||||||
|
required this.selectionMode,
|
||||||
|
});
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final bool selectionMode;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
final BoolCallback itemSelectionChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ItemListTile> createState() => _ItemListTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ItemListTileState extends State<ItemListTile> {
|
||||||
|
bool isSelected = false;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(widget.title),
|
||||||
|
subtitle: Text(widget.description),
|
||||||
|
onTap: _onTap,
|
||||||
|
onLongPress: _onLongPress,
|
||||||
|
selected: isSelected,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLongPress() {
|
||||||
|
setState(() => isSelected = true);
|
||||||
|
widget.itemSelectionChanged(isSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTap() {
|
||||||
|
if (isSelected || widget.selectionMode) {
|
||||||
|
setState(() => isSelected = !isSelected);
|
||||||
|
widget.itemSelectionChanged(isSelected);
|
||||||
|
} else {
|
||||||
|
widget.onTap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user