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,
});
static List<EquipmentProfileData>? of(BuildContext context) {
static List<EquipmentProfileData>? of(BuildContext context, {bool listen = true}) {
if (listen) {
return context.dependOnInheritedWidgetOfExactType<EquipmentProfiles>()?.profiles;
} else {
return context.findAncestorWidgetOfExactType<EquipmentProfiles>()?.profiles;
}
}
@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';
class EquipmentListTilesSection extends StatefulWidget {
class EquipmentProfileContainer extends StatefulWidget {
final EquipmentProfileData data;
final VoidCallback onExpand;
final VoidCallback onDelete;
const EquipmentListTilesSection({
const EquipmentProfileContainer({
required this.data,
required this.onExpand,
required this.onDelete,
super.key,
});
@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 FocusNode _fieldFocusNode = FocusNode();
bool _expanded = false;
@ -93,22 +95,28 @@ class _EquipmentListTilesSectionState extends State<EquipmentListTilesSection> {
Widget _collapseButton() {
return IconButton(
onPressed: () {
onPressed: _expanded ? collapse : expand,
icon: Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
);
}
void expand() {
widget.onExpand();
setState(() {
_expanded = !_expanded;
_expanded = true;
});
if (_expanded) {
SchedulerBinding.instance.addPostFrameCallback((_) {
Scrollable.ensureVisible(
context,
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
);
});
} else {
}
void collapse() {
setState(() {
_expanded = false;
});
_fieldFocusNode.unfocus();
}
},
icon: Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
);
}
}

View file

@ -3,7 +3,7 @@ import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/providers/equipment_profile_provider.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 {
const EquipmentProfileScreen({super.key});
@ -13,6 +13,22 @@ class EquipmentProfileScreen extends StatefulWidget {
}
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
Widget build(BuildContext context) {
return Scaffold(
@ -34,21 +50,38 @@ class _EquipmentProfileScreenState extends State<EquipmentProfileScreen> {
kFloatingActionButtonMargin,
),
separatorBuilder: (context, index) => const SizedBox(height: Dimens.grid16),
itemCount: EquipmentProfiles.of(context)?.length ?? 0,
itemBuilder: (_, index) => EquipmentListTilesSection(
itemCount: profilesCount,
itemBuilder: (context, index) => EquipmentProfileContainer(
key: profileContainersKeys[index],
data: EquipmentProfiles.of(context)![index],
onExpand: () => _keepExpandedAt(index),
onDelete: () {
EquipmentProfileProvider.of(context)
.deleteProfile(EquipmentProfiles.of(context)![index]);
profileContainersKeys.removeAt(index);
},
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
onPressed: EquipmentProfileProvider.of(context).addProfile,
floatingActionButton: profilesCount < maxProfiles
? FloatingActionButton(
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();
});
}
}