optimierung

pull/5/head
Bogdan Kotikov 2023-06-02 01:42:56 +02:00
parent c91f3901dd
commit a989878cca
10 changed files with 301 additions and 254 deletions

View File

@ -14,7 +14,7 @@ class AndroidApp extends StatelessWidget {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
scaffoldBackgroundColor: Colors.grey.shade100, //<-- SEE scaffoldBackgroundColor: Colors.grey.shade200, //<-- SEE
), ),
home: box.get("USER") == null ? const OnboardingPage() : const MainPage(), home: box.get("USER") == null ? const OnboardingPage() : const MainPage(),
routes: { routes: {

View File

@ -45,12 +45,9 @@ class CardComponent extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
height: 300, height: 300,
decoration: BoxDecoration( decoration: const BoxDecoration(
color: const Color(0xFF6E7BFB), color: Color(0xFF6E7BFB),
borderRadius: const BorderRadius.all(Radius.circular(16)), borderRadius: BorderRadius.all(Radius.circular(16)),
border: Border.all(
color: Colors.black,
),
), ),
margin: const EdgeInsets.fromLTRB(0, 16, 0, 16), margin: const EdgeInsets.fromLTRB(0, 16, 0, 16),
child: Column( child: Column(

View File

@ -11,7 +11,10 @@ class CardComponent extends StatefulWidget {
final bool addButtonVisible; final bool addButtonVisible;
const CardComponent( const CardComponent(
{Key? key, required this.eatingMealName, required this.selectedMeal, this.addButtonVisible = true}) {Key? key,
required this.eatingMealName,
required this.selectedMeal,
this.addButtonVisible = true})
: super(key: key); : super(key: key);
@override @override
@ -40,11 +43,14 @@ class _CardComponentState extends State<CardComponent> {
} }
getImageOfMeal() { getImageOfMeal() {
if (widget.eatingMealName.toLowerCase() == dotenv.env['BREAKFAST_FIELD']!.toLowerCase()) { if (widget.eatingMealName.toLowerCase() ==
dotenv.env['BREAKFAST_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/tea.png')); return const Image(image: AssetImage('assets/images/tea.png'));
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['LUNCH_FIELD']!.toLowerCase()) { } else if (widget.eatingMealName.toLowerCase() ==
dotenv.env['LUNCH_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/fries.png')); return const Image(image: AssetImage('assets/images/fries.png'));
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['DINNER_FIELD']!.toLowerCase()) { } else if (widget.eatingMealName.toLowerCase() ==
dotenv.env['DINNER_FIELD']!.toLowerCase()) {
return const Image(image: AssetImage('assets/images/ice.png')); return const Image(image: AssetImage('assets/images/ice.png'));
} }
} }
@ -60,7 +66,7 @@ class _CardComponentState extends State<CardComponent> {
} }
Widget getElevatedButton() { Widget getElevatedButton() {
if(widget.addButtonVisible){ if (widget.addButtonVisible) {
return ElevatedButton( return ElevatedButton(
onPressed: () async { onPressed: () async {
Navigator.of(context).push(createRoute(widget.eatingMealName)); Navigator.of(context).push(createRoute(widget.eatingMealName));
@ -74,18 +80,17 @@ class _CardComponentState extends State<CardComponent> {
style: TextStyle(fontSize: 28), style: TextStyle(fontSize: 28),
), ),
); );
}else{ } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
} }
int getCountedCalories() { int getCountedCalories() {
double calories = 0; double calories = 0;
for (Food food in widget.selectedMeal) { for (Food food in widget.selectedMeal) {
if (food.calories is int){ if (food.calories is int) {
calories += food.calories as int; calories += food.calories as int;
}else if(food.calories is double){ } else if (food.calories is double) {
calories += food.calories as double; calories += food.calories as double;
} }
} }
@ -94,60 +99,52 @@ class _CardComponentState extends State<CardComponent> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Container(
margin: const EdgeInsets.fromLTRB(0, 24, 0, 0), margin: const EdgeInsets.fromLTRB(0, 16, 0, 0),
child: Column( child: Column(
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( getImageOfMeal(),
children: [ Text(
getImageOfMeal(), StringUtils.capitalize(widget.eatingMealName),
Column( maxLines: 1,
mainAxisAlignment: MainAxisAlignment.start, overflow: TextOverflow.ellipsis,
children: [ softWrap: false,
SizedBox( style: const TextStyle(
width: MediaQuery.of(context).size.width * 0.6, color: Colors.black,
child: Text( fontWeight: FontWeight.w500,
StringUtils.capitalize(widget.eatingMealName), fontSize: 14),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 14),
),
),
],
)
],
), ),
getElevatedButton(), getElevatedButton(),
], ],
), ),
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width * 0.8, width: MediaQuery.of(context).size.width * 1,
child:ListView.builder( child: ListView.builder(
primary: false, primary: false,
shrinkWrap: true, shrinkWrap: true,
itemCount: getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal).keys.length, itemCount: getMapOfDistinctElementsWithCounterAndCalories(
widget.selectedMeal)
.keys
.length,
itemBuilder: (context, i) { itemBuilder: (context, i) {
Map<String,List<int>> map = getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal); Map<String, List<int>> map =
getMapOfDistinctElementsWithCounterAndCalories(
widget.selectedMeal);
String foodName = map.keys.elementAt(i); String foodName = map.keys.elementAt(i);
List<int> values = map.values.elementAt(i); List<int> values = map.values.elementAt(i);
return Text( return Text(getFoodListStringByFood(
getFoodListStringByFood(foodName, values[0], values[1]) foodName, values[0], values[1]));
); }),
}
),
), ),
widget.selectedMeal.isNotEmpty widget.selectedMeal.isNotEmpty
? const Divider() ? Column(
: const SizedBox.shrink(), children: [
widget.selectedMeal.isNotEmpty const Divider(),
? Text("${getCountedCalories()} kcal") Text("${getCountedCalories()} kcal")
],
)
: const SizedBox.shrink(), : const SizedBox.shrink(),
], ],
)); ));

View File

@ -10,17 +10,18 @@ class MealPageStatisticsFoodComponent extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
margin: const EdgeInsets.fromLTRB(0, 16, 0, 0),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white color: Colors.white,
), borderRadius: BorderRadius.all(Radius.circular(8))),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(
height: 24,
),
const TitleComponent("Nahrung"), const TitleComponent("Nahrung"),
FoodComponent(box: Hive.box(StatisticsService.instance.todayStatisticsBoxName),) FoodComponent(
box: Hive.box(StatisticsService.instance.todayStatisticsBoxName),
)
], ],
), ),
); );

View File

@ -34,9 +34,7 @@ class _DaysMealPageState extends State<DaysMealPageComponent> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Row(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
DaysTextComponent( DaysTextComponent(
@ -65,7 +63,6 @@ class _DaysMealPageState extends State<DaysMealPageComponent> {
index: 2 index: 2
), ),
], ],
),
); );
} }
} }

View File

@ -15,8 +15,6 @@ class StatisticsPercentage extends StatelessWidget {
valueListenable: StatisticsService.instance.ingredients, valueListenable: StatisticsService.instance.ingredients,
builder: (context, value, child) { builder: (context, value, child) {
return Container( return Container(
decoration: BoxDecoration(
border: Border.all(width: 2.0, color: Colors.black)),
height: heightStatisticsContainer, height: heightStatisticsContainer,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 0), padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 0),
child: Row( child: Row(

View File

@ -36,9 +36,12 @@ class MainPageState extends State<MainPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
extendBodyBehindAppBar: false,
appBar: AppBar( appBar: AppBar(
title: Text(pages[currentIndex].title), title: Text(pages[currentIndex].title),
backgroundColor: Colors.grey.shade100, backgroundColor: Colors.transparent,
foregroundColor: Colors.grey.shade400,
elevation: 0,
), ),
body: Padding( body: Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8),

View File

@ -24,16 +24,28 @@ class _MealPlanState extends State<MealPlanPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Container( body: SizedBox(
margin: const EdgeInsets.all(8),
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: const [ children: [
DaysMealPageComponent(), Container(
StatisticsPercentage(), decoration: const BoxDecoration(
MealPageStatisticsFoodComponent(), color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8))),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
child: Column(
children: const [
DaysMealPageComponent(),
StatisticsPercentage(),
],
),
),
),
const MealPageStatisticsFoodComponent(),
], ],
), ),
))); )));

View File

@ -20,160 +20,204 @@ class ProgressPage extends StatelessWidget {
return getTitle; return getTitle;
} }
/*
* TODO: in versch. Dateien auslagern, damit der Code nicht voll gemüllt wird
* */
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: SingleChildScrollView( body: SingleChildScrollView(
child: Padding( child: Column(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8), children: [
child: Column( Container(
children: [ decoration: const BoxDecoration(
ValueListenableBuilder( color: Colors.white,
valueListenable: StatisticsService.instance.dailyAverageForCurrentWeek, borderRadius: BorderRadius.all(Radius.circular(8))),
builder: (context, value, child) { child: Padding(
return SizedBox( padding:
height: 100, const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
width: 400, child: Column(
child: Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, ValueListenableBuilder(
children: [ valueListenable: StatisticsService
const TitleComponent("Täglicher Durchschnitt (in kcal)"), .instance.dailyAverageForCurrentWeek,
const SizedBox( builder: (context, value, child) {
height: 10, return SizedBox(
), height: 100,
const SecondaryTextComponent("Durchschnittlich"), width: 400,
SecondaryBigTextComponent("${value.toString()} kcal/Tag"), child: Column(
], crossAxisAlignment: CrossAxisAlignment.start,
), children: [
); const TitleComponent("Kalorien"),
}, const SizedBox(
), height: 10,
ValueListenableBuilder( ),
valueListenable: StatisticsService.instance.barChartData, const SecondaryTextComponent(
builder: (context, value, child) { "Durchschnittlich"),
return SizedBox( SecondaryBigTextComponent(
height: 325, "${value.toString()} kcal/Tag"),
child: Column( ],
crossAxisAlignment: CrossAxisAlignment.start, ),
children: [ );
SizedBox( },
height: 15, // Adjust the height of the legend as needed ),
child: Row( ValueListenableBuilder(
mainAxisAlignment: MainAxisAlignment.center, valueListenable:
children: [ StatisticsService.instance.barChartData,
Container( builder: (context, value, child) {
margin: const EdgeInsets.symmetric(horizontal: 8.0), // Adjust the spacing between legend items return SizedBox(
height: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 15,
// Adjust the height of the legend as needed
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Container( Container(
width: 12, margin: const EdgeInsets.symmetric(
height: 12, horizontal: 8.0),
decoration: const BoxDecoration( // Adjust the spacing between legend items
color: Colors.red, // Use the color of the first bar rod for the legend item child: Row(
shape: BoxShape.circle, children: [
Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
color: Colors.red,
// Use the color of the first bar rod for the legend item
shape: BoxShape.circle,
),
),
const SizedBox(width: 4.0),
// Adjust the spacing between the color indicator and the legend label
const Text(
'Frühstück',
// Replace with your desired legend label
style: TextStyle(
fontSize:
12), // Adjust the font size of the legend labels
),
],
), ),
), ),
const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label Container(
const Text( margin: const EdgeInsets.symmetric(
'Frühstück', // Replace with your desired legend label horizontal: 8.0),
style: TextStyle(fontSize: 12), // Adjust the font size of the legend labels // Adjust the spacing between legend items
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
color: Colors.green,
// Use the color of the first bar rod for the legend item
shape: BoxShape.circle,
),
),
const SizedBox(width: 4.0),
// Adjust the spacing between the color indicator and the legend label
const Text(
'Mittagessen',
// Replace with your desired legend label
style: TextStyle(
fontSize:
12), // Adjust the font size of the legend labels
),
],
),
),
Container(
margin: const EdgeInsets.symmetric(
horizontal: 8.0),
// Adjust the spacing between legend items
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
color: Colors.yellow,
// Use the color of the first bar rod for the legend item
shape: BoxShape.circle,
),
),
const SizedBox(width: 4.0),
// Adjust the spacing between the color indicator and the legend label
const Text(
'Abendessen',
// Replace with your desired legend label
style: TextStyle(
fontSize:
12), // Adjust the font size of the legend labels
),
],
),
), ),
], ],
), ),
), ),
Container( Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0), // Adjust the spacing between legend items margin:
child: Row( const EdgeInsets.fromLTRB(0, 24, 0, 0),
children: [ height: 250,
Container( child: BarChart(
width: 12, BarChartData(
height: 12, barTouchData: barTouchData,
decoration: const BoxDecoration( titlesData: titlesData,
color: Colors.green, // Use the color of the first bar rod for the legend item borderData: borderData,
shape: BoxShape.circle, barGroups: value,
), gridData: FlGridData(show: false),
alignment: BarChartAlignment.spaceAround,
), ),
const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label ),
const Text(
'Mittagessen', // Replace with your desired legend label
style: TextStyle(fontSize: 12), // Adjust the font size of the legend labels
),
],
), ),
), ],
Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0), // Adjust the spacing between legend items
child: Row(
children: [
Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
color: Colors.yellow, // Use the color of the first bar rod for the legend item
shape: BoxShape.circle,
),
),
const SizedBox(width: 4.0), // Adjust the spacing between the color indicator and the legend label
const Text(
'Abendessen', // Replace with your desired legend label
style: TextStyle(fontSize: 12), // Adjust the font size of the legend labels
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top:50.0), // Adjust the margin value as needed
child: SizedBox(
height: 250,
child: BarChart(
BarChartData(
barTouchData: barTouchData,
titlesData: titlesData,
borderData: borderData,
barGroups: value,
gridData: FlGridData(show: false),
alignment: BarChartAlignment.spaceAround,
),
), ),
), );
), },
], ),
),
);
},
),
ValueListenableBuilder(
valueListenable: StatisticsService.instance.weeklyCaloryRanking,
builder: (context, value, child) {
return Column(
//TODO: Loop through the values and display them dynamically
children: [
const TitleComponent("Lebensmittel mit dem höchsten Kaloriengehalt"),
const SizedBox(height: 24,),
for (var item in value.toSet())
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SecondaryTextComponent(getWeeklyRankingString(item.name)),
SecondaryTextComponent(item.calories.toString()),
],
),
], ],
); ),
}, )),
), Container(
], margin: const EdgeInsets.fromLTRB(0, 16, 0, 0),
), decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8))),
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: ValueListenableBuilder(
valueListenable:
StatisticsService.instance.weeklyCaloryRanking,
builder: (context, value, child) {
return Column(
children: [
const TitleComponent(
"Lebensmittel mit dem höchsten Kaloriengehalt"),
const SizedBox(
height: 24,
),
for (var item in value.toSet())
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SecondaryTextComponent(
getWeeklyRankingString(item.name)),
SecondaryTextComponent(
item.calories.toString()),
],
),
],
);
},
),
))
],
), ),
), ),
); );
} }
BarTouchData get barTouchData => BarTouchData( BarTouchData get barTouchData => BarTouchData(
@ -240,56 +284,56 @@ class ProgressPage extends StatelessWidget {
} }
FlTitlesData get titlesData => FlTitlesData( FlTitlesData get titlesData => FlTitlesData(
show: true, show: true,
bottomTitles: AxisTitles( bottomTitles: AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
showTitles: true, showTitles: true,
reservedSize: 30, reservedSize: 30,
getTitlesWidget: getTitles, getTitlesWidget: getTitles,
),
), ),
topTitles: AxisTitles( ),
sideTitles: SideTitles(showTitles: false), topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
), ),
rightTitles: AxisTitles( ),
sideTitles: SideTitles( leftTitles: AxisTitles(
showTitles: false, sideTitles: SideTitles(
), showTitles: true,
), getTitlesWidget: (value, _) {
leftTitles: AxisTitles( // Return a custom widget for each axis value
sideTitles: SideTitles( return Container(
showTitles: true, constraints:
getTitlesWidget: (value, _) { const BoxConstraints.tightFor(width: double.infinity),
// Return a custom widget for each axis value child: Padding(
return Container( padding: const EdgeInsets.only(right: 3.0),
constraints: const BoxConstraints.tightFor(width: double.infinity), // Adjust the margin value as needed
child: Padding( child: FittedBox(
padding: const EdgeInsets.only(right: 3.0), // Adjust the margin value as needed fit: BoxFit.scaleDown,
child: FittedBox( alignment: Alignment.centerLeft,
fit: BoxFit.scaleDown, child: Text(
alignment: Alignment.centerLeft, value.toInt().toString(),
child: Text( style: const TextStyle(
value.toInt().toString(), color: Colors.orange,
style: const TextStyle( fontWeight: FontWeight.bold,
color: Colors.orange,
fontWeight: FontWeight.bold,
),
), ),
), ),
), ),
); ),
}, );
), },
) ),
); ));
FlBorderData get borderData => FlBorderData( FlBorderData get borderData => FlBorderData(
show: true, // Set to true to display the chart border show: true, // Set to true to display the chart border
border: const Border( border: const Border(
bottom: BorderSide(color: Colors.black, width: 1), bottom: BorderSide(color: Colors.black, width: 1),
left: BorderSide(color: Colors.black, width: 1),// Hide the left border left:
), BorderSide(color: Colors.black, width: 1), // Hide the left border
); ),
);
} }

View File

@ -23,9 +23,7 @@ void main() async {
await Hive.openBox(dotenv.env['STATISTICS_MAIN_BOX'] ?? 'STATISTICS_MAIN_BOX'); await Hive.openBox(dotenv.env['STATISTICS_MAIN_BOX'] ?? 'STATISTICS_MAIN_BOX');
await Hive.openBox(dotenv.env['MEALPLAN_BOX'] ?? 'MEALPLAN'); await Hive.openBox(dotenv.env['MEALPLAN_BOX'] ?? 'MEALPLAN');
await Hive.openBox<User>('USER_BOX'); await Hive.openBox<User>('USER_BOX');
//Hive.deleteFromDisk();
setupTodayBox(); setupTodayBox();
//mockDataForWholeWeek();
if (defaultTargetPlatform == TargetPlatform.android) { if (defaultTargetPlatform == TargetPlatform.android) {
runApp(const AndroidApp()); runApp(const AndroidApp());