Commit fdd480f
Changed files (5)
lib
model
lib/components/measurement_graph.dart
@@ -1,1 +1,11 @@
-// TODO
\ No newline at end of file
+import 'package:flutter/material.dart';
+
+class MeasurementGraph extends StatelessWidget {
+ const MeasurementGraph({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ // TODO: implement build
+ return Container();
+ }
+}
\ No newline at end of file
lib/components/measurement_list.dart
@@ -1,1 +1,65 @@
-// TODO
\ No newline at end of file
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class MeasurementList extends StatelessWidget {
+ const MeasurementList({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ // TODO: implement build
+ return Container(
+ child: Consumer<BloodPressureModel>(
+ builder: (context, model, child) {
+ List<BloodPressureRecord> items = model.getLastX(30);
+ if (items.isNotEmpty && items.first.diastolic > 0) {
+ return ListView.builder(
+ itemCount: items.length,
+ shrinkWrap: true,
+ itemBuilder: (context, index) {
+ return buildListItem(items[index]);
+ }
+ );
+ } else {
+ return const Text('Es existieren noch keine Werte');
+ }
+ })
+ );
+ }
+
+ Widget buildListItem(BloodPressureRecord record) {
+ return Container(
+ child: Row(
+ children: [
+ Expanded(
+ flex: 10,
+ child: Text(record.systolic.toString())
+ ),
+ Expanded(
+ flex: 10,
+ child: Text(record.diastolic.toString())
+ ),
+ Expanded(
+ flex: 10,
+ child: Text(record.pulse.toString())
+ ),
+ Expanded(
+ flex: 70,
+ child: Text(record.notes)
+ ),
+ ]
+ ),
+ );
+ }
+
+ Widget buildColumnSeperator() {
+ return const SizedBox(
+ width: 8,
+ );
+ }
+}
+
+class _MeasuredValueListItem {
+
+
+}
lib/model/blood_pressure.dart
@@ -8,13 +8,38 @@ class BloodPressureModel extends ChangeNotifier {
// All measurements (might get slow after some time)
UnmodifiableListView<BloodPressureRecord> get allMeasurements => UnmodifiableListView(_allMeasurements);
+ /// Adds a new measurement at the correct chronological position in the List.
+ /// If the measurement was taken at exactly the same time as an existing
+ /// measurement, the existing measurement gets replaced.
void add(BloodPressureRecord measurement) {
- _allMeasurements.add(measurement);
+ if (_allMeasurements.isNotEmpty &&
+ _allMeasurements.last.compareTo(measurement) >= 0) {
+ // naive approach; change algorithm
+ for (int i = 0; i < _allMeasurements.length; i++) {
+ if (_allMeasurements[i].compareTo(measurement) == 0) {
+ _allMeasurements[i] = measurement;
+ } else if (_allMeasurements[i].compareTo(measurement) > 0) {
+ _allMeasurements.insert(i, measurement);
+ }
+ }
+ } else {
+ _allMeasurements.add(measurement);
+ }
notifyListeners();
}
+
+ /// Returns the
+ UnmodifiableListView<BloodPressureRecord> getLastX(int count) {
+ final List<BloodPressureRecord> lastMeasurements = [];
+ // example length = 30 (last index 29) count = 5 => 29, 28, 27, 26, 25 (5)
+ for (int i = _allMeasurements.length-1; i>=_allMeasurements.length-count &&
+ i>=0; i--) {
+ lastMeasurements.add(_allMeasurements[i]); // new list gets sorted high to low
+ }
+ return UnmodifiableListView(lastMeasurements);
+ }
/* TODO:
- - getLast (x)
- bool deleteFromTime (timestamp)
- bool changeAtTime (newRecord)
*/
@@ -32,4 +57,15 @@ class BloodPressureRecord {
const BloodPressureRecord(
this.creationTime, this.systolic, this.diastolic, this.pulse, this.notes);
+
+ @override
+ int compareTo(BloodPressureRecord other) {
+ if (creationTime.isBefore(other.creationTime)) {
+ return -1;
+ } else if (creationTime.isAfter(other.creationTime)) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
}
\ No newline at end of file
lib/screens/add_measurement.dart
@@ -41,17 +41,13 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
],
validator: (String? value) {
if (value == null || value.isEmpty
- || (double.tryParse(value) == null)) {
+ || (int.tryParse(value) == null)) {
return 'Please enter a Number';
+ } else {
+ _systolic = int.tryParse(value) ?? -1;
}
return null;
},
- onSaved: (String? value) {
- if (value != null && value.isNotEmpty
- || (double.tryParse(value ?? "-1") != null)) {
- _systolic = double.tryParse(value ?? "-1") as int;
- }
- },
),
TextFormField(
decoration: const InputDecoration(
@@ -63,17 +59,13 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
],
validator: (String? value) {
if (value == null || value.isEmpty
- || (double.tryParse(value) == null)) {
+ || (int.tryParse(value) == null)) {
return 'Please enter a Number';
+ } else {
+ _diastolic = int.tryParse(value) ?? -1;
}
return null;
},
- onSaved: (String? value) {
- if (value != null && value.isNotEmpty
- || (double.tryParse(value ?? "-1") != null)) {
- _diastolic = double.tryParse(value ?? "-1") as int;
- }
- },
),
TextFormField(
decoration: const InputDecoration(
@@ -85,23 +77,19 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
],
validator: (String? value) {
if (value == null || value.isEmpty
- || (double.tryParse(value) == null)) {
+ || (int.tryParse(value) == null)) {
return 'Please enter a Number';
+ } else {
+ _pulse = int.tryParse(value) ?? -1;
}
return null;
},
- onSaved: (String? value) {
- if (value != null && value.isNotEmpty
- || (double.tryParse(value ?? "-1") != null)) {
- _pulse = double.tryParse(value ?? "-1") as int;
- }
- },
),
TextFormField(
decoration: const InputDecoration(
hintText: 'note (optional)'
),
- onSaved: (String? value) {
+ validator: (String? value) {
_note = value ?? "";
},
),
lib/screens/home.dart
@@ -1,15 +1,30 @@
import 'package:blood_pressure_app/screens/add_measurement.dart';
import 'package:flutter/material.dart';
+import 'package:blood_pressure_app/components/measurement_graph.dart';
+import 'package:blood_pressure_app/components/measurement_list.dart';
class AppHome extends StatelessWidget {
const AppHome({super.key});
@override
Widget build(BuildContext context) {
- // TODO: implement body
return Scaffold(
- body: ListView(
-
+ body: Center(
+ child: Container(
+ padding: const EdgeInsets.all(80),
+ child: Column(
+ children: const [
+ Expanded(
+ flex: 40,
+ child: MeasurementGraph()
+ ),
+ Expanded(
+ flex: 60,
+ child: MeasurementList()
+ ),
+ ]
+ ),
+ ),
),
floatingActionButton: Ink(
decoration: ShapeDecoration(