@@ -10,7 +10,11 @@ import 'package:carp_serializable/carp_serializable.dart';
1010// Global Health instance
1111final health = Health ();
1212
13- void main () => runApp (HealthApp ());
13+ void main () => runApp (
14+ const MaterialApp (
15+ home: HealthApp (),
16+ ),
17+ );
1418
1519class HealthApp extends StatefulWidget {
1620 const HealthApp ({super .key});
@@ -122,13 +126,12 @@ class HealthAppState extends State<HealthApp> {
122126 try {
123127 authorized =
124128 await health.requestAuthorization (types, permissions: permissions);
125-
129+
126130 // request access to read historic data
127131 await health.requestHealthDataHistoryAuthorization ();
128132
129133 // request access in background
130134 await health.requestHealthDataInBackgroundAuthorization ();
131-
132135 } catch (error) {
133136 debugPrint ("Exception in authorize: $error " );
134137 }
@@ -197,6 +200,26 @@ class HealthAppState extends State<HealthApp> {
197200 });
198201 }
199202
203+ /// Fetch single data point by UUID and type.
204+ Future <void > fetchDataByUUID ({
205+ required String uuid,
206+ required HealthDataType type,
207+ }) async {
208+ try {
209+ // fetch health data
210+ HealthDataPoint ? healthPoint = await health.getHealthDataByUUID (
211+ uuid: uuid,
212+ type: type,
213+ );
214+
215+ if (healthPoint != null ) {
216+ openDetailBottomSheet (healthPoint);
217+ }
218+ } catch (error) {
219+ debugPrint ("Exception in getHealthDataByUUID: $error " );
220+ }
221+ }
222+
200223 /// Add some random health data.
201224 /// Note that you should ensure that you have permissions to add the
202225 /// following data types.
@@ -514,6 +537,22 @@ class HealthAppState extends State<HealthApp> {
514537 });
515538 }
516539
540+ /// Display bottom sheet dialog of selected HealthDataPoint
541+ void openDetailBottomSheet (HealthDataPoint ? healthPoint) {
542+ if (! context.mounted) return ;
543+
544+ showModalBottomSheet (
545+ context: context,
546+ isScrollControlled: true ,
547+ shape: const RoundedRectangleBorder (
548+ borderRadius: BorderRadius .vertical (top: Radius .circular (16 )),
549+ ),
550+ builder: (BuildContext context) => _detailedBottomSheet (
551+ healthPoint: healthPoint,
552+ ),
553+ );
554+ }
555+
517556 // UI building below
518557
519558 @override
@@ -735,6 +774,12 @@ class HealthAppState extends State<HealthApp> {
735774 trailing:
736775 Text ((p.value as WorkoutHealthValue ).workoutActivityType.name),
737776 subtitle: Text ('${p .dateFrom } - ${p .dateTo }\n ${p .recordingMethod }' ),
777+ onTap: () {
778+ fetchDataByUUID (
779+ uuid: p.uuid,
780+ type: p.type,
781+ );
782+ },
738783 );
739784 }
740785 if (p.value is NutritionHealthValue ) {
@@ -750,6 +795,12 @@ class HealthAppState extends State<HealthApp> {
750795 title: Text ("${p .typeString }: ${p .value }" ),
751796 trailing: Text (p.unitString),
752797 subtitle: Text ('${p .dateFrom } - ${p .dateTo }\n ${p .recordingMethod }' ),
798+ onTap: () {
799+ fetchDataByUUID (
800+ uuid: p.uuid,
801+ type: p.type,
802+ );
803+ },
753804 );
754805 });
755806
@@ -806,4 +857,49 @@ class HealthAppState extends State<HealthApp> {
806857 AppState .PERMISSIONS_REVOKED => _permissionsRevoked,
807858 AppState .PERMISSIONS_NOT_REVOKED => _permissionsNotRevoked,
808859 };
860+
861+ Widget _detailedBottomSheet ({HealthDataPoint ? healthPoint}) {
862+ return DraggableScrollableSheet (
863+ expand: false ,
864+ initialChildSize: 0.5 ,
865+ minChildSize: 0.3 ,
866+ maxChildSize: 0.9 ,
867+ builder: (BuildContext listContext, scrollController) {
868+ return Container (
869+ padding: const EdgeInsets .all (16 ),
870+ child: Column (
871+ children: [
872+ const Text (
873+ "Health Data Details" ,
874+ style: TextStyle (fontSize: 18 , fontWeight: FontWeight .bold),
875+ ),
876+ const SizedBox (height: 10 ),
877+ healthPoint == null
878+ ? const Text ('UUID Not Found!' )
879+ : Expanded (
880+ child: ListView .builder (
881+ controller: scrollController,
882+ itemCount: healthPoint.toJson ().entries.length,
883+ itemBuilder: (context, index) {
884+ String key =
885+ healthPoint.toJson ().keys.elementAt (index);
886+ var value = healthPoint.toJson ()[key];
887+
888+ return ListTile (
889+ title: Text (
890+ key.replaceAll ('_' , ' ' ).toUpperCase (),
891+ style:
892+ const TextStyle (fontWeight: FontWeight .bold),
893+ ),
894+ subtitle: Text (value.toString ()),
895+ );
896+ },
897+ ),
898+ ),
899+ ],
900+ ),
901+ );
902+ },
903+ );
904+ }
809905}
0 commit comments