mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-25 00:40:39 +00:00
collapse on expand
This commit is contained in:
parent
2ef59d9eb6
commit
da02748806
4 changed files with 73 additions and 28 deletions
|
@ -77,8 +77,12 @@ class EquipmentProfiles extends InheritedWidget {
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
static List<EquipmentProfileData>? of(BuildContext context) {
|
static List<EquipmentProfileData>? of(BuildContext context, {bool listen = true}) {
|
||||||
return context.dependOnInheritedWidgetOfExactType<EquipmentProfiles>()?.profiles;
|
if (listen) {
|
||||||
|
return context.dependOnInheritedWidgetOfExactType<EquipmentProfiles>()?.profiles;
|
||||||
|
} else {
|
||||||
|
return context.findAncestorWidgetOfExactType<EquipmentProfiles>()?.profiles;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -4,21 +4,23 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
import 'components/equipment_list_tiles/widget_list_tiles_equipments.dart';
|
import 'components/equipment_list_tiles/widget_list_tiles_equipments.dart';
|
||||||
|
|
||||||
class EquipmentListTilesSection extends StatefulWidget {
|
class EquipmentProfileContainer extends StatefulWidget {
|
||||||
final EquipmentProfileData data;
|
final EquipmentProfileData data;
|
||||||
|
final VoidCallback onExpand;
|
||||||
final VoidCallback onDelete;
|
final VoidCallback onDelete;
|
||||||
|
|
||||||
const EquipmentListTilesSection({
|
const EquipmentProfileContainer({
|
||||||
required this.data,
|
required this.data,
|
||||||
|
required this.onExpand,
|
||||||
required this.onDelete,
|
required this.onDelete,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EquipmentListTilesSection> createState() => _EquipmentListTilesSectionState();
|
State<EquipmentProfileContainer> createState() => EquipmentProfileContainerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
|
class EquipmentProfileContainerState extends State<EquipmentProfileContainer> {
|
||||||
final TextEditingController _nameController = TextEditingController(text: 'Default');
|
final TextEditingController _nameController = TextEditingController(text: 'Default');
|
||||||
final FocusNode _fieldFocusNode = FocusNode();
|
final FocusNode _fieldFocusNode = FocusNode();
|
||||||
bool _expanded = false;
|
bool _expanded = false;
|
||||||
|
@ -93,22 +95,28 @@ class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
|
||||||
|
|
||||||
Widget _collapseButton() {
|
Widget _collapseButton() {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
onPressed: () {
|
onPressed: _expanded ? collapse : expand,
|
||||||
setState(() {
|
|
||||||
_expanded = !_expanded;
|
|
||||||
});
|
|
||||||
if (_expanded) {
|
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
|
||||||
Scrollable.ensureVisible(
|
|
||||||
context,
|
|
||||||
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_fieldFocusNode.unfocus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
|
icon: Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expand() {
|
||||||
|
widget.onExpand();
|
||||||
|
setState(() {
|
||||||
|
_expanded = true;
|
||||||
|
});
|
||||||
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||||
|
Scrollable.ensureVisible(
|
||||||
|
context,
|
||||||
|
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void collapse() {
|
||||||
|
setState(() {
|
||||||
|
_expanded = false;
|
||||||
|
});
|
||||||
|
_fieldFocusNode.unfocus();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
import 'components/equipment_profile_section/widget_section_equipment_profile.dart';
|
import 'components/equipment_profile_container/widget_container_equipment_profile.dart';
|
||||||
|
|
||||||
class EquipmentProfileScreen extends StatefulWidget {
|
class EquipmentProfileScreen extends StatefulWidget {
|
||||||
const EquipmentProfileScreen({super.key});
|
const EquipmentProfileScreen({super.key});
|
||||||
|
@ -13,6 +13,22 @@ class EquipmentProfileScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
||||||
|
static const maxProfiles = 5; // replace with a constant from iap
|
||||||
|
|
||||||
|
late List<GlobalKey<EquipmentProfileContainerState>> profileContainersKeys = [];
|
||||||
|
|
||||||
|
int get profilesCount => EquipmentProfiles.of(context)?.length ?? 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
profileContainersKeys = List.filled(
|
||||||
|
EquipmentProfiles.of(context, listen: false)?.length ?? 0,
|
||||||
|
GlobalKey<EquipmentProfileContainerState>(),
|
||||||
|
growable: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -34,21 +50,38 @@ class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
|
||||||
kFloatingActionButtonMargin,
|
kFloatingActionButtonMargin,
|
||||||
),
|
),
|
||||||
separatorBuilder: (context, index) => const SizedBox(height: Dimens.grid16),
|
separatorBuilder: (context, index) => const SizedBox(height: Dimens.grid16),
|
||||||
itemCount: EquipmentProfiles.of(context)?.length ?? 0,
|
itemCount: profilesCount,
|
||||||
itemBuilder: (_, index) => EquipmentListTilesSection(
|
itemBuilder: (context, index) => EquipmentProfileContainer(
|
||||||
|
key: profileContainersKeys[index],
|
||||||
data: EquipmentProfiles.of(context)![index],
|
data: EquipmentProfiles.of(context)![index],
|
||||||
|
onExpand: () => _keepExpandedAt(index),
|
||||||
onDelete: () {
|
onDelete: () {
|
||||||
EquipmentProfileProvider.of(context)
|
EquipmentProfileProvider.of(context)
|
||||||
.deleteProfile(EquipmentProfiles.of(context)![index]);
|
.deleteProfile(EquipmentProfiles.of(context)![index]);
|
||||||
|
profileContainersKeys.removeAt(index);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: profilesCount < maxProfiles
|
||||||
onPressed: EquipmentProfileProvider.of(context).addProfile,
|
? FloatingActionButton(
|
||||||
child: const Icon(Icons.add),
|
onPressed: () {
|
||||||
),
|
EquipmentProfileProvider.of(context).addProfile();
|
||||||
|
profileContainersKeys.add(GlobalKey<EquipmentProfileContainerState>());
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _keepExpandedAt(int index) {
|
||||||
|
profileContainersKeys.getRange(0, index).forEach((element) {
|
||||||
|
element.currentState?.collapse();
|
||||||
|
});
|
||||||
|
profileContainersKeys.getRange(index + 1, profilesCount).forEach((element) {
|
||||||
|
element.currentState?.collapse();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue