Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BMI calculator example #130

Merged
merged 2 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions bmi_calculator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.DS_Store
.dart_tool/

.vscode/

.packages
.pub/

.idea/
.vagrant/
.sconsign.dblite
.svn/

migrate_working_dir/

*.swp
profile

DerivedData/

.generated/

*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3

!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3

xcuserdata

*.moved-aside

*.pyc
*sync/
Icon?
.tags*

build/
.android/
.ios/
.flutter-plugins
.flutter-plugins-dependencies

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json
10 changes: 10 additions & 0 deletions bmi_calculator/.metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: f1875d570e39de09040c8f79aa13cc56baab8db1
channel: stable

project_type: module
7 changes: 7 additions & 0 deletions bmi_calculator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# bmi_calculator

A person’s Body-Mass Index, or BMI, helps them check whether they’re a healthy weight for their height. If a person weighs less or more than the recommended weight for their height, it could lead to health issues in the future. While BMI is not the only factor individuals should consider while working on their health and fitness, it is a good starting point. To understand what your BMI is, you need to know your height and weight. You can then use an online BMI calculator to check your BMI, which will help you understand if you’re underweight, a healthy weight, overweight or obese. Or, you can measure your height in metres and weight in kilograms. Divide your weight by your height squared to calculate your BMI.

BMI Calculator [Wiki](https://en.wikipedia.org/wiki/Body_mass_index)


4 changes: 4 additions & 0 deletions bmi_calculator/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
9 changes: 9 additions & 0 deletions bmi_calculator/lib/bmi_calculator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'dart:math';

import 'package:bmi_calculator/body_model.dart';

// I've used weight/height^2 (kg/m^2)
// You can expand this logic
double calculateBMI({required BodyModel bodyModel}) {
return (bodyModel.weight) / pow(bodyModel.height / 100, 2);
}
19 changes: 19 additions & 0 deletions bmi_calculator/lib/body_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
enum Sex {
male,
female,
}

// User body model class
class BodyModel {
Sex sex;
int height;
int weight;
int age;

BodyModel({
required this.sex,
required this.height,
required this.weight,
required this.age,
});
}
38 changes: 38 additions & 0 deletions bmi_calculator/lib/calculator/calculate_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';

import '../palette.dart';

class CalculateButton extends StatelessWidget {
const CalculateButton({
super.key,
required this.onTap,
});

final VoidCallback onTap;

@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 12,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Palette.action,
),
child: TextButton(
style: ButtonStyle(
overlayColor:
MaterialStateProperty.all(Colors.white.withOpacity(0.10)),
),
onPressed: onTap,
child: const Text(
'CALCULATE YOUR BMI',
style: TextStyle(
color: Palette.textActive,
fontSize: 20,
),
),
),
);
}
}
105 changes: 105 additions & 0 deletions bmi_calculator/lib/calculator/calculator_body.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import 'package:bmi_calculator/calculator/calculate_button.dart';
import 'package:flutter/material.dart';
import 'package:bmi_calculator/calculator/height_widget.dart';
import 'package:bmi_calculator/calculator/int_picker_widget.dart';
import 'package:bmi_calculator/calculator/sex_widget.dart';
import 'package:bmi_calculator/result/result_page.dart';
import 'package:bmi_calculator/body_model.dart';
import 'package:bmi_calculator/palette.dart';

class CalculatorBody extends StatefulWidget {
const CalculatorBody({
super.key,
required this.model,
});

final BodyModel model;

@override
State<CalculatorBody> createState() => _CalculatorBodyState();
}

class _CalculatorBodyState extends State<CalculatorBody> {
@override
Widget build(BuildContext context) {
return Container(
color: Palette.background,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SexWidget(
sex: widget.model.sex,
onMaleTap: () => setState(() {
// Set sex to male
widget.model.sex = Sex.male;
}),
onFemaleTap: () => setState(() {
// Set sex to female
widget.model.sex = Sex.female;
})),
HeightWidget(
height: widget.model.height,
onHeightChanged: (height) => setState(() {
// Set height and round to Int
widget.model.height = height.toInt();
}),
),
SizedBox(
height: (MediaQuery.of(context).size.width - 48) / 2,
child: Row(
children: [
Expanded(
// Weight widget
child: IntPickerWidget(
title: 'Weight',
onIncreaseTap: () => setState(() {
// Increase weight
widget.model.weight++;
}),
onDecreaseTap: () => setState(() {
// Decrease weight
widget.model.weight--;
}),
value: widget.model.weight,
),
),
const SizedBox(
width: 5,
),
Expanded(
// Age widget
child: IntPickerWidget(
title: 'Age',
onIncreaseTap: () => setState(() {
// Increase age
widget.model.age++;
}),
onDecreaseTap: () => setState(() {
// Decrease age
widget.model.age--;
}),
value: widget.model.age,
),
)
],
),
),
CalculateButton(
onTap: () {
// Navigate to Result Page
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => ResultPage(model: widget.model)),
),
);
},
),
],
),
),
);
}
}
31 changes: 31 additions & 0 deletions bmi_calculator/lib/calculator/calculator_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:bmi_calculator/calculator/calculator_body.dart';
import 'package:flutter/material.dart';
import 'package:bmi_calculator/body_model.dart';
import 'package:bmi_calculator/palette.dart';

class CalculatorPage extends StatelessWidget {
CalculatorPage({
Key? key,
required this.title,
}) : super(key: key);

final String title;

final BodyModel model = BodyModel(
sex: Sex.male,
height: 183,
weight: 74,
age: 19,
);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
backgroundColor: Palette.background,
),
body: CalculatorBody(model: model),
);
}
}
83 changes: 83 additions & 0 deletions bmi_calculator/lib/calculator/height_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import 'package:flutter/material.dart';

import '../palette.dart';

class HeightWidget extends StatelessWidget {
const HeightWidget({
super.key,
required this.height,
required this.onHeightChanged,
});

final int height;
final Function(double) onHeightChanged;

@override
Widget build(BuildContext context) {
return Container(
height: (MediaQuery.of(context).size.width - 48) / 2,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Palette.cardBackgroundInactive,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'HEIGHT',
style: TextStyle(
fontSize: 23,
fontWeight: FontWeight.w600,
color: Palette.textInactive,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
height.round().toString(),
style: const TextStyle(
fontSize: 50,
fontWeight: FontWeight.w800,
color: Palette.textActive,
),
),
const Text(
'cm',
style: TextStyle(
fontSize: 30,
color: Palette.textInactive,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 1.0,
thumbShape: const RoundSliderThumbShape(
enabledThumbRadius: 15,
),
),
child: Slider(
value: height.toDouble(),
min: 150.0,
max: 210.0,
activeColor: Palette.textActive,
inactiveColor: Palette.textInactive,
thumbColor: Palette.action,
onChanged: onHeightChanged,
),
),
),
],
),
);
}
}
Loading