refactored list items into seperate class

This commit is contained in:
andrei 2021-11-23 18:33:41 -05:00
parent 9d4ac739c2
commit 88fb731a07
3 changed files with 110 additions and 58 deletions

View File

@ -15,14 +15,16 @@ class BoxChecker extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', title: 'Flutter Demo',
// starting with dark theme but changing the primary colors manually
theme: ThemeData.from(colorScheme: const ColorScheme.dark()).copyWith( theme: ThemeData.from(colorScheme: const ColorScheme.dark()).copyWith(
canvasColor: Colors.blueGrey[900], canvasColor: Colors.blueGrey[900],
cardColor: Colors.grey[800],
scaffoldBackgroundColor: Colors.black12, scaffoldBackgroundColor: Colors.black12,
shadowColor: Colors.black38, shadowColor: Colors.black38,
toggleableActiveColor: Colors.blue, toggleableActiveColor: Colors.blue,
colorScheme: ColorScheme.fromSwatch( colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
cardColor: Colors.grey[800],
backgroundColor: Colors.black12,
), ),
), ),
themeMode: ThemeMode.dark, themeMode: ThemeMode.dark,

View File

@ -1,3 +1,4 @@
import 'package:boxchecker/check_list_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'data_util.dart' as data; import 'data_util.dart' as data;
import 'db_helper.dart'; import 'db_helper.dart';
@ -11,7 +12,7 @@ class CheckList extends StatefulWidget {
} }
class _CheckList extends State<CheckList> { class _CheckList extends State<CheckList> {
bool _editable = false; late bool _editable;
data.List? listData; data.List? listData;
List<data.Check> list = []; List<data.Check> list = [];
@ -29,6 +30,7 @@ class _CheckList extends State<CheckList> {
void _loadListData() async { void _loadListData() async {
var rows = await DBHelper.dbHelper.getListData(widget.id); var rows = await DBHelper.dbHelper.getListData(widget.id);
listData = (rows.isNotEmpty) ? data.List.fromMap(rows[0]) : null; listData = (rows.isNotEmpty) ? data.List.fromMap(rows[0]) : null;
_editable = (listData != null && !listData!.isTemplate!);
} }
void _addItem() async { void _addItem() async {
@ -40,14 +42,6 @@ class _CheckList extends State<CheckList> {
}); });
} }
void _removeItem(data.Check item) async {
DBHelper.dbHelper.deleteItem(item);
}
void _updateItem(data.Check item) async {
DBHelper.dbHelper.updateItem(item);
}
void _toggleEditable() { void _toggleEditable() {
setState(() { setState(() {
_editable = !_editable; _editable = !_editable;
@ -87,65 +81,25 @@ class _CheckList extends State<CheckList> {
child: ListView.builder( child: ListView.builder(
itemCount: list.length, itemCount: list.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Dismissible( return CheckListItem(
key: Key(list[index].id.toString()),
confirmDismiss: (direction) async { confirmDismiss: (direction) async {
var item = list[index]; if (!_editable) return false;
if (direction == DismissDirection.endToStart) { if (direction == DismissDirection.endToStart) {
setState(() { setState(() {
_removeItem(item); DBHelper.dbHelper.deleteItem(list[index]);
list.removeAt(index); list.removeAt(index);
}); });
return true; return true;
} }
_updateItem(item); DBHelper.dbHelper.updateItem(list[index]);
setState(() { setState(() {
item.value = !item.value; list[index].value = !list[index].value;
}); });
return false; return false;
}, },
background: Container( item: list[index],
color: Colors.blue, locked: !_editable,
child: Row(children: const [
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.check),
),
Spacer(),
]),
),
secondaryBackground: Container(
color: Colors.red,
child: Row(children: const [
Spacer(),
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.delete_forever)),
]),
),
child: CheckboxListTile(
title: TextFormField(
enabled: (listData != null &&
(!listData!.isTemplate! || _editable)),
decoration: const InputDecoration(border: InputBorder.none),
initialValue: list[index].text,
onChanged: (value) {
list[index].text = value;
_updateItem(list[index]);
},
),
controlAffinity: ListTileControlAffinity.leading,
value: list[index].value,
onChanged: (listData != null &&
(!listData!.isTemplate! || _editable))
? ((value) {
_updateItem(list[index]);
setState(() {
list[index].value = value!;
});
})
: null,
),
); );
}, },
), ),

96
lib/check_list_item.dart Normal file
View File

@ -0,0 +1,96 @@
import 'package:boxchecker/check_list.dart';
import 'package:flutter/material.dart';
import 'data_util.dart' as data;
import 'db_helper.dart';
typedef FutureCallback = Future<bool?> Function(DismissDirection);
class CheckListItem extends StatefulWidget {
const CheckListItem(
{Key? key,
required this.item,
required this.confirmDismiss,
this.locked = false})
: super(key: key);
final data.Check item;
final FutureCallback confirmDismiss;
final bool locked;
@override
State<StatefulWidget> createState() => _CheckListItem();
}
class _CheckListItem extends State<CheckListItem> {
Widget dismissIconPadding(Widget icon) {
return Padding(
padding: const EdgeInsets.all(10),
child: icon,
);
}
Widget dismissBackground() {
return Container(
color: Colors.blue,
child: Row(children: const [
Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.check),
),
Spacer(),
]));
}
Widget dismissSecondaryBackground() {
return Container(
color: Colors.red,
child: Row(children: [
const Spacer(),
dismissIconPadding(const Icon(Icons.delete_forever)),
]),
);
}
Widget dismissLockedBackground() {
return Container(
color: Colors.grey[900],
child: Row(
children: [
dismissIconPadding(const Icon(Icons.lock)),
const Spacer(),
dismissIconPadding(const Icon(Icons.lock)),
],
));
}
@override
Widget build(BuildContext context) {
return Dismissible(
key: Key(widget.item.id.toString()),
background:
!widget.locked ? dismissBackground() : dismissLockedBackground(),
secondaryBackground: !widget.locked ? dismissSecondaryBackground() : null,
confirmDismiss: widget.confirmDismiss,
child: CheckboxListTile(
title: TextFormField(
enabled: !widget.locked,
decoration: const InputDecoration(border: InputBorder.none),
initialValue: widget.item.text,
onChanged: (value) {
widget.item.text = value;
DBHelper.dbHelper.updateItem(widget.item);
},
),
controlAffinity: ListTileControlAffinity.leading,
value: widget.item.value,
onChanged: !widget.locked
? ((value) {
DBHelper.dbHelper.updateItem(widget.item);
setState(() {
widget.item.value = value!;
});
})
: null,
),
);
}
}