import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_application_1/enums.dart'; import 'package:flutter_application_1/translations.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'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', 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 createState() => _MyHomePageState(); } class _MyHomePageState extends State { // 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; // Anfangskapital double _monthlySavingsRate = 0.0; // Monatliche Sparrate double _interestRate = 0.0; // Jährlicher Zinssatz double _time = 0.0; // Anlagezeitraum in Jahren double _investedMoney = 0.0; // Investiertes Geld ohne Zinsen final List _investedMoneyList = []; // Investiertes Geld ohne Zinsen (pro Jahr) PayoutInterval _payoutInterval = PayoutInterval.yearly; // Standardwert für das Ausschüttungsintervall double _compoundInterest = 0.0; // Investiertes Geld mit Zinsen final List _compoundInterestList = []; // Investiertes Geld mit Zinsen (pro Jahr) bool _calculationPerformed = false; // 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); }); } // Methode zum Berechnen des investierten Geldes void _calculateInvestedMoney() { setState(() { _investedMoneyList.clear(); _investedMoney = _initialCapital; for (int i = 0; i < _time; i++) { _investedMoney += _monthlySavingsRate * 12; _investedMoney = _investedMoney.roundToDouble(); _investedMoneyList.add(_investedMoney); } _calculationPerformed = true; }); } // Methode zum Berechnen der Zinsen void _calculateCompoundInterest() { setState(() { _compoundInterestList.clear(); _compoundInterest = _initialCapital; if(_payoutInterval == PayoutInterval.yearly){ for(int i = 0; i < _time; i++){ _compoundInterest += _compoundInterest * (_interestRate / 100) + _monthlySavingsRate * 12; _compoundInterest = _compoundInterest.roundToDouble(); _compoundInterestList.add(_compoundInterest - _investedMoneyList[i]); } } else{ for(int i = 0; i < _time; i++){ for(int j = 0; j < 12; j++){ _compoundInterest += _compoundInterest * ((_interestRate / 100) / 12) + _monthlySavingsRate; _compoundInterest = _compoundInterest.roundToDouble(); } _compoundInterestList.add(_compoundInterest - _investedMoneyList[i]); } } _calculationPerformed = true; }); } @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: [ buildInputWidget('Anfangskapital', _initialCapitalController, _initialCapitalFocusNode, _isInitialCapitalEntered, '€', 'Das Anfangskapital ist der Betrag, den Sie zu Beginn Ihrer Anlage haben.'), buildInputWidget('Monatliche Sparrate', _monthlySavingsRateController, _monthlySavingsRateFocusNode, _isMonthlySavingsRateEntered, '€', 'Die monatliche Sparrate ist der Betrag, den Sie jeden Monat zu Ihrer Investition hinzufügen.'), buildInputWidget('Jährlicher Zinssatz', _interestRateController, _interestRateFocusNode, _isInterestRateEntered, '%', 'Der jährliche Zinssatz ist der Prozentsatz, zu dem Ihr investiertes Kapital jedes Jahr wächst.'), buildInputWidget('Anlagezeitraum', _timeController, _timeFocusNode, _isTimeEntered, 'Jahre', '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: () { setInitialCapital(); setMonthlySavingsRate(); setInterestRate(); setTime(); _calculateInvestedMoney(); _calculateCompoundInterest(); }, style: ButtonStyle( backgroundColor: MaterialStateProperty.all(CupertinoColors.black), foregroundColor: MaterialStateProperty.all(CupertinoColors.white), ), child: const Text( 'Berechnen', style: TextStyle( fontWeight: FontWeight.bold, ), ), ), const SizedBox(height: 20), if(_calculationPerformed) buildResultWidget('$_compoundInterest', '$_investedMoney', '$_time', '$_monthlySavingsRate', '$_interestRate', _payoutInterval, _investedMoneyList, _compoundInterestList), ], ), ) ) ) ); } }