refactored list items into seperate class
This commit is contained in:
parent
9d4ac739c2
commit
88fb731a07
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue