@@ -41,6 +41,8 @@ class _EditFeatureAttachmentsState extends State<EditFeatureAttachments>
4141 ),
4242 ),
4343 );
44+ // The currently selected feature.
45+ ArcGISFeature ? _selectedFeature;
4446
4547 @override
4648 Widget build (BuildContext context) {
@@ -50,6 +52,16 @@ class _EditFeatureAttachmentsState extends State<EditFeatureAttachments>
5052 onMapViewReady: onMapViewReady,
5153 onTap: onTap,
5254 ),
55+ // If a feature is selected, show the bottom sheet to manage its attachments.
56+ bottomSheet: _selectedFeature == null
57+ ? null
58+ : AttachmentsOptions (
59+ arcGISFeature: _selectedFeature! ,
60+ applyEdits: _applyEdits,
61+ onCloseIconPressed: () {
62+ setState (() => _selectedFeature = null );
63+ },
64+ ),
5365 );
5466 }
5567
@@ -80,27 +92,15 @@ class _EditFeatureAttachmentsState extends State<EditFeatureAttachments>
8092
8193 // If there are features identified, show the bottom sheet to display the
8294 // attachment information for the selected feature.
83- final features = identifyLayerResult.geoElements
84- .whereType <Feature >()
85- .toList ();
86- if (features.isNotEmpty) {
87- _featureLayer.selectFeatures (features);
88- final selectedFeature = features.first as ArcGISFeature ;
89- if (mounted) _showBottomSheet (selectedFeature);
95+ final feature = identifyLayerResult.geoElements
96+ .whereType <ArcGISFeature >()
97+ .firstOrNull;
98+ setState (() => _selectedFeature = feature);
99+ if (feature != null ) {
100+ _featureLayer.selectFeatures ([feature]);
90101 }
91102 }
92103
93- // Show the bottom sheet to display the attachment information.
94- void _showBottomSheet (ArcGISFeature selectedFeature) {
95- showModalBottomSheet <void >(
96- context: context,
97- builder: (context) => AttachmentsOptions (
98- arcGISFeature: selectedFeature,
99- applyEdits: _applyEdits,
100- ),
101- );
102- }
103-
104104 // Apply the changes to the feature table.
105105 Future <void > _applyEdits (ArcGISFeature selectedFeature) async {
106106 final serviceFeatureTable =
@@ -124,10 +124,12 @@ class AttachmentsOptions extends StatefulWidget {
124124 const AttachmentsOptions ({
125125 required this .arcGISFeature,
126126 required this .applyEdits,
127+ required this .onCloseIconPressed,
127128 super .key,
128129 });
129130 final ArcGISFeature arcGISFeature;
130131 final FutureOr <void > Function (ArcGISFeature ) applyEdits;
132+ final void Function () onCloseIconPressed;
131133
132134 @override
133135 State <AttachmentsOptions > createState () => _AttachmentsOptionsState ();
@@ -136,104 +138,88 @@ class AttachmentsOptions extends StatefulWidget {
136138// State class for the AttachmentsOptions.
137139class _AttachmentsOptionsState extends State <AttachmentsOptions >
138140 with SampleStateSupport {
139- late final String _damageType;
141+ String ? _damageType;
140142 var _attachments = < Attachment > [];
141- var _isLoading = false ;
143+ var _isLoading = true ;
142144
143145 @override
144146 void initState () {
145147 super .initState ();
146- _damageType = widget.arcGISFeature.attributes['typdamage' ] as String ? ?? '' ;
148+ _damageType = widget.arcGISFeature.attributes['typdamage' ] as String ? ;
147149 _loadAttachments ();
148150 }
149151
152+ @override
153+ void didUpdateWidget (covariant AttachmentsOptions oldWidget) {
154+ super .didUpdateWidget (oldWidget);
155+
156+ // If the selected feature has changed, reload the attachments.
157+ if (oldWidget.arcGISFeature.attributes['objectId' ] !=
158+ widget.arcGISFeature.attributes['objectId' ]) {
159+ _attachments = [];
160+ _isLoading = true ;
161+ _damageType = widget.arcGISFeature.attributes['typdamage' ] as String ? ;
162+ _loadAttachments ();
163+ }
164+ }
165+
150166 @override
151167 Widget build (BuildContext context) {
152- return Stack (
153- children: [
154- Column (
155- children: [
156- // Display the damage type and a close button.
157- Container (
158- color: Colors .purple,
159- padding: const EdgeInsets .fromLTRB (5 , 0 , 5 , 0 ),
160- child: Row (
161- mainAxisAlignment: MainAxisAlignment .spaceBetween,
162- children: [
163- Text (
164- 'Damage Type: $_damageType ' ,
165- style: const TextStyle (
166- fontSize: 18 ,
167- fontWeight: FontWeight .bold,
168- color: Colors .white,
168+ // Present a bottom sheet with attachment options.
169+ return BottomSheetSettings (
170+ onCloseIconPressed: widget.onCloseIconPressed,
171+ title: 'Damage Type: $_damageType ' ,
172+ settingsWidgets: (context) => [
173+ Container (
174+ constraints: BoxConstraints (
175+ maxHeight: MediaQuery .sizeOf (context).height * 0.5 ,
176+ ),
177+ child: SingleChildScrollView (
178+ child: Column (
179+ children: [
180+ Row (
181+ children: [
182+ // Display the number of attachments.
183+ const Text ('Number of Attachments: ' ),
184+ if (_isLoading)
185+ const SizedBox (
186+ height: 18 ,
187+ width: 18 ,
188+ child: CircularProgressIndicator (),
189+ )
190+ else
191+ Text ('${_attachments .length }' ),
192+ const Spacer (),
193+ // A button to add an attachment.
194+ ElevatedButton (
195+ onPressed: addAttachment,
196+ child: const Text ('Add Attachment' ),
169197 ),
170- ),
171- if (_isLoading)
172- const SizedBox (
173- height: 18 ,
174- width: 18 ,
175- child: CircularProgressIndicator (color: Colors .white),
176- )
177- else
178- const SizedBox .shrink (),
179- IconButton (
180- icon: const Icon (Icons .close),
181- onPressed: () => Navigator .pop (context),
182- ),
183- ],
184- ),
185- ),
186-
187- // Display the number of attachments.
188- Padding (
189- padding: const EdgeInsets .fromLTRB (5 , 0 , 5 , 0 ),
190- child: Row (
191- mainAxisAlignment: MainAxisAlignment .spaceBetween,
192- children: [
193- Text ('Number of Attachments: ${_attachments .length }' ),
194- ElevatedButton (
195- onPressed: addAttachment,
196- child: const Text ('Add Attachment' ),
197- ),
198- ],
199- ),
200- ),
201- const Divider (color: Colors .purple),
202-
203- // Display each attachment with view and delete buttons.
204- SingleChildScrollView (
205- child: Column (
206- children: [
207- ListView .builder (
208- itemCount: _attachments.length,
209- shrinkWrap: true ,
210- padding: const EdgeInsets .all (2 ),
211- itemBuilder: (context, index) {
212- return ListTile (
213- title: Text (_attachments[index].name),
214- subtitle: Text (_attachments[index].contentType),
215- trailing: Row (
216- mainAxisSize: MainAxisSize .min,
217- children: [
218- IconButton (
219- icon: const Icon (Icons .remove_red_eye),
220- onPressed: () =>
221- viewAttachment (_attachments[index]),
222- ),
223- IconButton (
224- icon: const Icon (Icons .delete),
225- onPressed: () =>
226- deleteAttachment (_attachments[index]),
227- ),
228- ],
198+ ],
199+ ),
200+ // Display each attachment with view and delete buttons.
201+ ..._attachments.map (
202+ (attachment) => ListTile (
203+ title: Text (attachment.name),
204+ subtitle: Text (attachment.contentType),
205+ trailing: Row (
206+ mainAxisSize: MainAxisSize .min,
207+ children: [
208+ IconButton (
209+ icon: const Icon (Icons .remove_red_eye),
210+ onPressed: () => viewAttachment (attachment),
211+ ),
212+ IconButton (
213+ icon: const Icon (Icons .delete),
214+ onPressed: () => deleteAttachment (attachment),
229215 ),
230- );
231- } ,
216+ ],
217+ ) ,
232218 ),
233- ] ,
234- ) ,
219+ ) ,
220+ ] ,
235221 ),
236- ] ,
222+ ) ,
237223 ),
238224 ],
239225 );
0 commit comments