import 'dart:convert'; import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; import 'package:healthcare_user/BMI/bmi_history.dart'; import 'package:healthcare_user/common/settings.dart'; class BMICalculator extends StatefulWidget { const BMICalculator({Key? key}) : super(key: key); @override State createState() => _BMICalculatorState(); } class _BMICalculatorState extends State { TextEditingController heightController = TextEditingController(); TextEditingController inchesController = TextEditingController(); TextEditingController cmsController = TextEditingController(); TextEditingController weightController = TextEditingController(); TextEditingController ageController = TextEditingController(); TextEditingController dateInput = TextEditingController(); String bmiValue = ''; String bmiText = ''; Color bmiTextColor = Colors.black; var heightUnitItems = [ 'feet', 'cm', ]; var heightUnits = 'feet'; var weightUnitItems = [ 'kg', ]; var weightUnits = 'kg'; @override void initState() { ageController.text = AppSettings.age; super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppSettings.appBar('Calculate BMI'), body: SingleChildScrollView( child: Container( child: Padding( padding: EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ TextFormField( cursorColor: greyColor, controller: ageController, textCapitalization: TextCapitalization.characters, keyboardType: TextInputType.number, decoration: const InputDecoration( prefixIcon: Icon( Icons.person, color: primaryColor, ), suffixText: "Yrs", border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Age', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), SizedBox(height: 10), DropdownButtonFormField( // Initial Value value: heightUnits, isExpanded: true, decoration: const InputDecoration( prefixIcon: Icon( Icons.ac_unit_outlined, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Select Height units', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), hint: Text('Units'), // Down Arrow Icon //icon: const Icon(Icons.keyboard_arrow_down), // Array list of items items: heightUnitItems.map((String items) { return DropdownMenuItem( value: items, child: Text( items, style: TextStyle( fontSize: 16, ), textAlign: TextAlign.center, )); }).toList(), // After selecting the desired option,it will // change button value to selected value onChanged: (String? newValue) { setState(() { heightUnits = newValue!; }); }, ), SizedBox(height: 10), Visibility( visible: heightUnits == 'feet', child: Container( //height: 60, child: Row( children: [ Expanded( child: TextFormField( cursorColor: greyColor, controller: heightController, textCapitalization: TextCapitalization.characters, keyboardType: TextInputType.number, decoration: const InputDecoration( prefixIcon: Icon( Icons.height, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Feets', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), ), SizedBox(width: 5), Expanded( child: TextFormField( cursorColor: greyColor, controller: inchesController, textCapitalization: TextCapitalization.characters, keyboardType: TextInputType.number, decoration: const InputDecoration( prefixIcon: Icon( Icons.height, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Inches', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), ), SizedBox(width: 5), ], ), ), ), Visibility( visible: heightUnits == 'cm', child: Container( //height: 60, child: Row( children: [ Expanded( child: TextFormField( cursorColor: greyColor, controller: cmsController, textCapitalization: TextCapitalization.characters, keyboardType: TextInputType.number, decoration: const InputDecoration( prefixIcon: Icon( Icons.height, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Enter height in cms', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), ), ], ), ), ), SizedBox(height: 10), Container( //height: 40, padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), child: Row( children: [ Expanded( child: TextFormField( cursorColor: greyColor, controller: weightController, textCapitalization: TextCapitalization.characters, keyboardType: TextInputType.number, decoration: const InputDecoration( prefixIcon: Icon( Icons.line_weight_outlined, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Weight', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), ), SizedBox(width: 5), Expanded( child: DropdownButtonFormField( // Initial Value value: weightUnits, isExpanded: true, decoration: const InputDecoration( prefixIcon: Icon( Icons.ac_unit_outlined, color: primaryColor, ), border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), labelText: 'Units', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), hint: Text('Units'), // Down Arrow Icon //icon: const Icon(Icons.keyboard_arrow_down), // Array list of items items: weightUnitItems.map((String items) { return DropdownMenuItem( value: items, child: Text( items, style: TextStyle( fontSize: 16, ), textAlign: TextAlign.center, )); }).toList(), // After selecting the desired option,it will // change button value to selected value onChanged: (String? newValue) { setState(() { weightUnits = newValue!; }); }, ), ) ], ), ), SizedBox(height: 10), Container( child: TextFormField( cursorColor: greyColor, controller: dateInput, decoration: textFormFieldDecorationBMI( Icons.calendar_today, 'Enter Date'), readOnly: true, onTap: () async { DateTime? pickedDate = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(1950), lastDate: DateTime.now(), builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.dark().copyWith( colorScheme: ColorScheme.dark( primary: buttonColors, onPrimary: Colors.white, surface: buttonColors, onSurface: Colors.white, ), dialogBackgroundColor: primaryColor, ), child: child!, ); }, ); if (pickedDate != null) { print( pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000 String formattedDate = DateFormat('dd-MM-yyyy').format(pickedDate); print( formattedDate); //formatted date output using intl package => 2021-03-16 setState(() { dateInput.text = formattedDate; //set output date to TextField value. }); } else {} }, ), ), SizedBox(height: 10), Container( width: double.infinity, height: MediaQuery.of(context).size.height * .05, child: ElevatedButton( style: ElevatedButton.styleFrom( primary: buttonColors, // background onPrimary: Colors.black, // foreground ), onPressed: () async { if (ageController.text != '' && heightController.text != '' || cmsController.text != '' && weightController.text != '' && dateInput.text != '') { if (int.parse(heightController.text) > 7) { AppSettings.longFailedToast( 'Please enter feet below 8 feets'); } else if (int.parse(inchesController.text) > 12) { AppSettings.longFailedToast( 'Please enter inches below 12'); } else if (int.parse(heightController.text) == 0 && int.parse(inchesController.text) < 6) { AppSettings.longFailedToast( 'Please enter inches above 6'); } else { AppSettings.preLoaderDialog(context); var payload = new Map(); if (heightUnits.toString().toLowerCase() == 'feet') { cmsController.text = ''; } else { heightController.text = ''; inchesController.text = ''; } payload["age"] = int.parse(ageController.text.toString()); payload["feet"] = heightController.text.toString(); payload["inches"] = inchesController.text.toString(); payload["height"] = cmsController.text.toString(); payload["weight"] = weightController.text.toString(); payload["heightUnit"] = heightUnits.toString(); payload["weightUnit"] = weightUnits.toString(); payload["date"] = dateInput.text.toString(); try { var value = await AppSettings.calculateBmi(payload); var valueResponse = jsonDecode(value); Navigator.of(context, rootNavigator: true).pop(); heightController.clear(); cmsController.clear(); inchesController.clear(); weightController.clear(); dateInput.clear(); setState(() { bmiValue = valueResponse['userDetails'] ['bmivalue'] .toString(); if (double.parse(bmiValue) < 18.5) { bmiText = 'Underweight'; bmiTextColor=Colors.red; } else if (double.parse(bmiValue) >= 18.5 && double.parse(bmiValue) <= 24.9) { bmiText = 'Normal weight'; bmiTextColor=buttonColors; } else if (double.parse(bmiValue) >= 25 && double.parse(bmiValue) <= 29.9) { bmiText = 'Overweight'; bmiTextColor=Colors.red; } else if (double.parse(bmiValue) >= 30) { bmiText = 'Obesity'; bmiTextColor=Colors.red; } }); } catch (e) { Navigator.of(context, rootNavigator: true).pop(); AppSettings.longFailedToast( 'Calculating BMI failed'); } } } else { AppSettings.longFailedToast( 'Please enter valid details'); } }, child: const Text('Calculate BMI'), )), SizedBox(height: 20), Container( child: Row( children: [ Text( 'Your BMI value: $bmiValue', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), ), SizedBox( width: 10, ), Text(bmiText, style: TextStyle( color: bmiTextColor, fontWeight: FontWeight.bold,fontSize: 20)), ], )), SizedBox(height: 30), Container( child: Text( 'Underweight = <18.5', style: bmiTextStyle(), ), ), SizedBox(height: 10), Container( child: Text('Normal weight = 18.5–24.9', style: bmiTextStyle()), ), SizedBox(height: 10), Container( child: Text('Overweight = 25–29.9', style: bmiTextStyle()), ), SizedBox(height: 10), Container( child: Text('Obesity = BMI of 30 or greater', style: bmiTextStyle()), ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( children: [ IconButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => BMIHistory()), ); }, icon: Icon( Icons.history, color: primaryColor, size: 40, ), ), SizedBox(height: 10), Padding( padding: EdgeInsets.fromLTRB(10, 0, 0, 0), child: Container( child: Text('History', style: TextStyle( color: Colors.black, fontSize: 12, fontWeight: FontWeight.bold, )), ), ) ], ), ElevatedButton( style: ElevatedButton.styleFrom( primary: buttonColors, // background onPrimary: Colors.black, // foreground ), onPressed: () async { Navigator.pop(context); }, child: const Text('Cancel'), ) ], ) ], ), )), )); } }