collapse on expand

This commit is contained in:
Vadim 2023-03-20 23:02:20 +03:00
parent 2ef59d9eb6
commit da02748806
4 changed files with 73 additions and 28 deletions

View file

@ -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

View file

@ -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();
}
} }

View file

@ -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();
});
}
} }