flutter_application_1/lib/main.dart

279 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_application_1/calculator.dart';
import 'package:flutter_application_1/enums.dart';
import 'package:flutter_application_1/utils.dart';
import 'package:flutter_application_1/widgets/input_widget.dart';
import 'package:flutter_application_1/widgets/interval_widget.dart';
import 'package:flutter_application_1/widgets/result_widget.dart';
import 'package:flutter_application_1/widgets/error_widget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Zinseszinsrechner',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: CupertinoColors.white, background: CupertinoColors.white),
useMaterial3: true,
),
home: const MyHomePage(title: 'Zinseszinsrechner',),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Controller und Fokus-Knoten für die Eingabefelder
final TextEditingController _initialCapitalController = TextEditingController();
final TextEditingController _monthlySavingsRateController = TextEditingController();
final TextEditingController _interestRateController = TextEditingController();
final TextEditingController _timeController = TextEditingController();
final FocusNode _initialCapitalFocusNode = FocusNode();
final FocusNode _monthlySavingsRateFocusNode = FocusNode();
final FocusNode _interestRateFocusNode = FocusNode();
final FocusNode _timeFocusNode = FocusNode();
// Zustandsvariablen für die Validierung der Eingaben
bool _isInitialCapitalEntered = false;
bool _isMonthlySavingsRateEntered = false;
bool _isInterestRateEntered = false;
bool _isTimeEntered = false;
@override
void initState() {
super.initState();
// Listener für die Eingabefelder, um die Validierung durchzuführen und Standardwerte wiederherzustellen
_initialCapitalController.addListener(() {
setState(() {
_isInitialCapitalEntered = _initialCapitalController.text.isNotEmpty &&
isNumeric(_initialCapitalController.text);
restoreDefaultValuesIfEmpty(_initialCapitalController);
});
});
_monthlySavingsRateController.addListener(() {
setState(() {
_isMonthlySavingsRateEntered = _monthlySavingsRateController.text.isNotEmpty &&
isNumeric(_monthlySavingsRateController.text);
restoreDefaultValuesIfEmpty(_monthlySavingsRateController);
});
});
_interestRateController.addListener(() {
setState(() {
_isInterestRateEntered = _interestRateController.text.isNotEmpty &&
isNumeric(_interestRateController.text);
restoreDefaultValuesIfEmpty(_interestRateController);
});
});
_timeController.addListener(() {
setState(() {
_isTimeEntered = _timeController.text.isNotEmpty &&
isNumeric(_timeController.text);
restoreDefaultValuesIfEmpty(_timeController);
});
});
// Listener für die Fokus-Knoten, um die Eingabe zu runden, wenn der Fokus verloren geht
_initialCapitalFocusNode.addListener(() {
if (!_initialCapitalFocusNode.hasFocus) {
roundToInteger(_initialCapitalController);
}
});
_monthlySavingsRateFocusNode.addListener(() {
if (!_monthlySavingsRateFocusNode.hasFocus) {
roundToInteger(_monthlySavingsRateController);
}
});
_interestRateFocusNode.addListener(() {
if (!_interestRateFocusNode.hasFocus) {
roundToInteger(_interestRateController);
}
});
_timeFocusNode.addListener(() {
if (!_timeFocusNode.hasFocus) {
roundToInteger(_timeController);
}
});
// Setzen von Beispielwerten für die Eingabefelder
_initialCapitalController.text = '1000';
_monthlySavingsRateController.text = '50';
_interestRateController.text = '5';
_timeController.text = '10';
}
double _initialCapital = 0.0; // Das anfängliche Kapital
double _monthlySavingsRate = 0.0; // Der monatliche Sparbetrag
double _interestRate = 0.0; // Der jährliche Zinssatz
double _time = 0.0; // Der Anlagezeitraum in Jahren
double _investedMoney = 0.0; // Das investierte Geld
final List<double> _investedMoneyList = []; // Liste, die das investierte Geld pro Jahr speichert
PayoutInterval _payoutInterval = PayoutInterval.yearly; // Das Auszahlungsintervall (jährlich oder monatlich)
double _compoundInterest = 0.0; // Der Zinseszins
final List<double> _compoundInterestList = []; // Liste, die den Zinseszins pro Jahr speichert
// Methoden zum Festlegen der Werte aus den Eingabefeldern
void setInitialCapital() {
setState(() {
_initialCapital = double.parse(_initialCapitalController.text);
});
}
void setMonthlySavingsRate() {
setState(() {
_monthlySavingsRate = double.parse(_monthlySavingsRateController.text);
});
}
void setInterestRate() {
setState(() {
_interestRate = double.parse(_interestRateController.text);
});
}
void setTime() {
setState(() {
_time = double.parse(_timeController.text);
});
}
CalculationPerformed _isCalculated = CalculationPerformed.noFirstTimeItLoaded;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
InputWidget(
label: 'Anfangskapital',
controller: _initialCapitalController,
focusNode: _initialCapitalFocusNode,
isValid: _isInitialCapitalEntered,
suffixText: '',
tooltipText: 'Das Anfangskapital ist der Betrag, den Sie zu Beginn Ihrer Anlage haben.'
),
InputWidget(
label: 'Monatliche Sparrate',
controller: _monthlySavingsRateController,
focusNode: _monthlySavingsRateFocusNode,
isValid: _isMonthlySavingsRateEntered,
suffixText: '',
tooltipText: 'Die monatliche Sparrate ist der Betrag, den Sie jeden Monat zu Ihrer Investition hinzufügen.'
),
InputWidget(
label: 'Jährlicher Zinssatz',
controller: _interestRateController,
focusNode: _interestRateFocusNode,
isValid: _isInterestRateEntered,
suffixText: '%',
tooltipText: 'Der jährliche Zinssatz ist der Prozentsatz, zu dem Ihr investiertes Kapital jedes Jahr wächst.'
),
InputWidget(
label: 'Anlagezeitraum',
controller: _timeController,
focusNode: _timeFocusNode,
isValid: _isTimeEntered,
suffixText: 'Jahre',
tooltipText: 'Der Anlagezeitraum ist die Zeitspanne, für die Sie planen, Ihr Geld anzulegen.'
),
IntervalWidget(
selectedInterval: translateInterval(_payoutInterval),
onChanged: (newInterval) {
setState(() {
_payoutInterval = newInterval == 'jährlich' ? PayoutInterval.yearly : PayoutInterval.monthly;
});
},
),
ElevatedButton(
onPressed: () {
if (_isInitialCapitalEntered &&
_isMonthlySavingsRateEntered &&
_isInterestRateEntered &&
_isTimeEntered) {
setInitialCapital();
setMonthlySavingsRate();
setInterestRate();
setTime();
_investedMoney = calculateInvestedMoney(_initialCapital, _monthlySavingsRate, _time, _investedMoneyList);
_compoundInterest = calculateCompoundInterest(
_initialCapital,
_monthlySavingsRate,
_interestRate,
_time,
_payoutInterval,
_investedMoneyList,
_compoundInterestList
);
_isCalculated = CalculationPerformed.yes;
} else {
_isCalculated = CalculationPerformed.no;
}
setState(() {});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(CupertinoColors.black),
foregroundColor: MaterialStateProperty.all<Color>(CupertinoColors.white),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
),
),
child: const Text(
'Berechnen',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 20),
if(_isCalculated == CalculationPerformed.yes)
ResultWidget(
compoundInterest: '$_compoundInterest',
investedMoney: '$_investedMoney',
time: '$_time',
monthlySavingsRate: '$_monthlySavingsRate',
interestRate: '$_interestRate',
payoutInterval: _payoutInterval,
investedMoneyList: _investedMoneyList,
compoundInterestList: _compoundInterestList,
),
if(_isCalculated == CalculationPerformed.no)
const ErrWidget(
errorMessage: 'Ungültige Eingabe',
),
],
),
)
)
)
);
}
}