Skip to content

Instantly share code, notes, and snippets.

@YumNumm
Last active July 11, 2023 16:26
Show Gist options
  • Save YumNumm/82452362f8fcd41b638a9f320d287696 to your computer and use it in GitHub Desktop.
Save YumNumm/82452362f8fcd41b638a9f320d287696 to your computer and use it in GitHub Desktop.
BMIを算出するFlutter Application
import 'package:flutter/material.dart';
void main() => runApp(const App());
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const HomePage(),
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("BMI Calc")),
body: const Padding(
padding: EdgeInsets.all(16),
child: HomePageBody(),
),
);
}
}
class HomePageBody extends StatefulWidget {
const HomePageBody({super.key});
@override
State<HomePageBody> createState() => _HomePageBodyState();
}
class _HomePageBodyState extends State<HomePageBody> {
double? _height;
double? _weight;
@override
Widget build(BuildContext context) {
final bmi = switch ((_height, _weight)) {
(double height, double weight) => weight / (height * height),
_ => null,
};
final obesityType = switch (bmi) {
double _ => Obesity.fromBmi(bmi),
_ => null,
};
final obesityColor = switch (obesityType) {
Obesity.low => Colors.blue,
Obesity.standard => Colors.green,
Obesity.obesity1 => Colors.yellow,
Obesity.obesity2 => Colors.orange,
Obesity.obesity3 => Colors.red,
Obesity.obesity4 => Colors.purple,
_ => Colors.grey,
};
/// 適正体重
final properWeight = switch (_height) {
double height => height * height * 22,
_ => null,
};
final textTheme = Theme.of(context).textTheme;
final resultWidget = AnimatedSwitcher(
duration: const Duration(milliseconds: 100),
child: DecoratedBox(
key: ValueKey(obesityType),
decoration: BoxDecoration(
color: obesityColor,
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text(
switch ((bmi, obesityType)) {
(double bmi, Obesity obesityType) =>
'${bmi.toStringAsFixed(2)} ${obesityType.name}',
_ => "入力してください",
},
style: textTheme.displaySmall!.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
if (properWeight != null)
Text(
'適正体重: ${properWeight.toStringAsFixed(2)}kg',
style: textTheme.titleLarge,
),
],
),
),
),
);
return Column(
children: [
const Text("身長(m)を入力してください"),
TextFormField(
onChanged: (String value) =>
setState(() => _height = double.tryParse(value)),
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: "身長(m)を入力してください",
),
keyboardType: const TextInputType.numberWithOptions(decimal: true),
),
const SizedBox(height: 16),
const Text("体重(kg)を入力してください"),
TextFormField(
onChanged: (String value) =>
setState(() => _weight = double.tryParse(value)),
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: "体重(kg)を入力してください",
),
keyboardType: const TextInputType.numberWithOptions(decimal: true),
),
const SizedBox(height: 16),
resultWidget,
],
);
}
}
/// 日本肥満学会の定義による肥満度の判定
enum Obesity {
/// 低体重
low,
/// 標準体重
standard,
/// 肥満(1度)
obesity1,
/// 肥満(2度)
obesity2,
/// 肥満(3度)
obesity3,
/// 肥満(4度)
obesity4,
;
/// BMIから肥満度を判定する
static Obesity fromBmi(double bmi) => switch (bmi) {
< 18.5 => Obesity.low,
< 25 => Obesity.standard,
< 30 => Obesity.obesity1,
< 35 => Obesity.obesity2,
< 40 => Obesity.obesity3,
_ => Obesity.obesity4,
};
String get name => switch (this) {
Obesity.low => "低体重",
Obesity.standard => "標準体重",
Obesity.obesity1 => "肥満(1度)",
Obesity.obesity2 => "肥満(2度)",
Obesity.obesity3 => "肥満(3度)",
Obesity.obesity4 => "肥満(4度)",
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment