Major design change to Neumorphic design

main
Arlind 2023-06-14 00:26:04 +02:00
parent 7b8dec7b5a
commit 392a02b38d
15 changed files with 688 additions and 170 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,48 +1,65 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:tests/preferences.dart';
import 'package:tests/theme/theme_constants.dart';
import 'package:tests/theme/theme_manager.dart';
void main() { void main() {
runApp(FinancialPlannerApp()); runApp(const FinancialPlannerApp());
} }
ThemeManager _themeManager = ThemeManager();
class FinancialPlannerApp extends StatelessWidget { class FinancialPlannerApp extends StatelessWidget {
const FinancialPlannerApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Financial Planner', title: 'Financial Planner',
theme: ThemeData( theme: lightTheme,
brightness: Brightness.light, darkTheme: darkTheme,
primarySwatch: Colors.blue, themeMode: _themeManager.themeMode,
), home: const HomePage(),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.blue,
),
home: HomePage(),
); );
} }
} }
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({super.key});
@override @override
_HomePageState createState() => _HomePageState(); HomePageState createState() => HomePageState();
} }
class _HomePageState extends State<HomePage> { class HomePageState extends State<HomePage> {
List<Account> accounts = []; List<Account> accounts = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_themeManager.addListener(themeListener);
loadAccounts(); loadAccounts();
}
}
@override
void dispose() {
_themeManager.removeListener(themeListener);
super.dispose();
}
themeListener(){
if(mounted){
setState(() {
});
}
}
Future<void> loadAccounts() async { Future<void> loadAccounts() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
final accountList = prefs.getStringList('accounts') ?? []; final accountList = prefs.getStringList('accounts') ?? [];
@ -82,58 +99,91 @@ class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Financial Planner'), centerTitle: true,
), backgroundColor: Colors.transparent,
body: ListView.builder( elevation: 0,
itemCount: accounts.length, title: const Text(
itemBuilder: (context, index) { 'Financial Planner',
return ListTile( style: TextStyle(
title: Text(accounts[index].name), fontSize: 18,
subtitle: Text('Balance: \$${accounts[index].balance.toStringAsFixed(2)}'), fontWeight: FontWeight.bold,
onTap: () { color: Colors.black54,
Navigator.push( ),
context, ),
MaterialPageRoute( actions: [
builder: (context) => AccountDetailPage( Padding(
account: accounts[index], padding: const EdgeInsets.only(right: 16.0, top: 3, bottom: 7),
updateAccountBalance: updateAccountBalance, child: NeumorphicButton(
),
),
);
},
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () { onPressed: () {
showDialog( Navigator.push(
context: context, context,
builder: (BuildContext context) { MaterialPageRoute(builder: (context) => Settings()),
return AlertDialog(
title: Text('Delete Account'),
content: Text('Are you sure you want to delete this account?'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Cancel'),
),
TextButton(
onPressed: () {
deleteAccount(accounts[index]);
Navigator.of(context).pop();
},
child: Text('Delete'),
),
],
);
},
); );
}, },
style: NeumorphicStyle(
shape: NeumorphicShape.convex,
boxShape: NeumorphicBoxShape.circle(),
depth: 6,
intensity: 0.9,
color: Colors.grey.shade100,
),
child: Icon(Icons.settings, color: Colors.black38),
),
),
],
),
body: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: accounts.length,
itemBuilder: (context, index) {
return GestureDetector(
onLongPress: () {
AwesomeDialog(
btnOkText: "Delete",
btnOkColor: Colors.lightGreen,
btnCancelColor: Colors.grey,
context: context,
animType: AnimType.bottomSlide,
dialogType: DialogType.info,
title: 'Delete Account',
headerAnimationLoop: false,
desc: 'Are you sure you want to delete this account?',
btnCancelOnPress: () {},
btnOkOnPress: () {
deleteAccount(accounts[index]);
},
).show();
},
child: Neumorphic(
margin: const EdgeInsets.all(16),
style: NeumorphicStyle(
depth: 7,
intensity: 1,
shadowDarkColor: Colors.grey.shade300,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
),
child: ListTile(
title: Text(accounts[index].name),
subtitle: Text('Balance: \$${accounts[index].balance.toStringAsFixed(2)}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AccountDetailPage(
account: accounts[index],
updateAccountBalance: updateAccountBalance,
),
),
);
},
),
), ),
); );
}, },
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: NeumorphicButton(
onPressed: () { onPressed: () {
showDialog( showDialog(
context: context, context: context,
@ -144,7 +194,14 @@ class _HomePageState extends State<HomePage> {
}, },
); );
}, },
child: Icon(Icons.add), style: NeumorphicStyle(
depth: 8,
intensity: 1,
shadowDarkColor: Colors.grey.shade400,
color: Colors.grey.shade100,
boxShape: const NeumorphicBoxShape.circle(),
),
child: const Icon(Icons.add,size:60,color: Colors.black12,),
), ),
); );
} }
@ -178,13 +235,13 @@ class Account {
class AddAccountDialog extends StatefulWidget { class AddAccountDialog extends StatefulWidget {
final Function addAccount; final Function addAccount;
AddAccountDialog({required this.addAccount}); const AddAccountDialog({super.key, required this.addAccount});
@override @override
_AddAccountDialogState createState() => _AddAccountDialogState(); AddAccountDialogState createState() => AddAccountDialogState();
} }
class _AddAccountDialogState extends State<AddAccountDialog> { class AddAccountDialogState extends State<AddAccountDialog> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController(); final _nameController = TextEditingController();
final _balanceController = TextEditingController(); final _balanceController = TextEditingController();
@ -214,52 +271,123 @@ class _AddAccountDialogState extends State<AddAccountDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text('Add Account'), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
title: const Text(
'Add Account',
),
titleTextStyle: TextStyle(
color: Colors.black54,
fontSize: 20,
),
content: Form( content: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
TextFormField( Neumorphic(
controller: _nameController, style: NeumorphicStyle(
decoration: InputDecoration(labelText: 'Name'), depth: -5,
validator: (value) { intensity: 0.8,
if (value!.isEmpty) { color: Colors.grey.shade100,
return 'Please enter a name'; boxShape: NeumorphicBoxShape.roundRect(
} BorderRadius.circular(12),
return null; ),
}, ),
child: TextFormField(
controller: _nameController,
decoration: InputDecoration(
labelText: 'Name',
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(12, 16, 12, 16),
),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a name';
}
return null;
},
),
), ),
TextFormField( SizedBox(height: 16),
controller: _balanceController, Neumorphic(
decoration: InputDecoration(labelText: 'Balance'), style: NeumorphicStyle(
keyboardType: TextInputType.number, depth: -5,
validator: (value) { intensity: 0.8,
if (value!.isEmpty) { color: Colors.grey.shade100,
return 'Please enter a balance'; boxShape: NeumorphicBoxShape.roundRect(
} BorderRadius.circular(12),
if (double.tryParse(value) == null) { ),
return 'Please enter a valid number'; ),
} child: TextFormField(
return null; controller: _balanceController,
}, decoration: InputDecoration(
labelText: 'Balance',
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(12, 16, 12, 16),
),
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a balance';
}
if (double.tryParse(value) == null) {
return 'Please enter a valid number';
}
return null;
},
),
), ),
], ],
), ),
), ),
actions: [ actions: [
TextButton( NeumorphicButton(
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text('Cancel'), style: NeumorphicStyle(
shape: NeumorphicShape.concave,
intensity: 0.9,
depth: 9,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
color: Colors.grey.shade100,
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
'Cancel',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
), ),
TextButton( NeumorphicButton(
onPressed: _submitForm, onPressed: _submitForm,
child: Text('Add'), style: NeumorphicStyle(
shape: NeumorphicShape.concave,
intensity: 0.8,
depth: 9,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
color: Colors.grey.shade100,
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
'Add',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
), ),
], ],
); );
} }
} }
@ -268,13 +396,13 @@ class AccountDetailPage extends StatefulWidget {
final Account account; final Account account;
final Function(Account) updateAccountBalance; final Function(Account) updateAccountBalance;
AccountDetailPage({required this.account, required this.updateAccountBalance}); const AccountDetailPage({super.key, required this.account, required this.updateAccountBalance});
@override @override
_AccountDetailPageState createState() => _AccountDetailPageState(); AccountDetailPageState createState() => AccountDetailPageState();
} }
class _AccountDetailPageState extends State<AccountDetailPage> with SingleTickerProviderStateMixin { class AccountDetailPageState extends State<AccountDetailPage> with SingleTickerProviderStateMixin {
late TabController _tabController; late TabController _tabController;
List<Transaction> transactions = []; List<Transaction> transactions = [];
List<Transaction> incomeTransactions = []; List<Transaction> incomeTransactions = [];
@ -363,14 +491,49 @@ class _AccountDetailPageState extends State<AccountDetailPage> with SingleTicker
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(widget.account.name), backgroundColor: Colors.transparent,
elevation: 0,
toolbarHeight: 80,
title: Text(
widget.account.name,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black54,
),
),
centerTitle: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
),
shadowColor: Colors.grey.shade300,
leading: Padding(
padding: const EdgeInsets.only(left: 16.0),
child: NeumorphicButton(
onPressed: () {
Navigator.pop(context);
},
style: NeumorphicStyle(
shape: NeumorphicShape.flat,
boxShape: NeumorphicBoxShape.circle(),
depth: 6,
intensity: 0.9,
color: Colors.grey.shade100,
),
padding: EdgeInsets.all(10),
child: Icon(Icons.arrow_back, color: Colors.black38),
),
),
), ),
body: Column( body: Column(
children: [ children: [
TabBar( TabBar(
controller: _tabController, controller: _tabController,
labelColor: Colors.black, labelColor: Colors.black,
tabs: [ tabs: const [
Tab(text: 'Einnahmen'), Tab(text: 'Einnahmen'),
Tab(text: 'Ausgaben'), Tab(text: 'Ausgaben'),
], ],
@ -391,12 +554,24 @@ class _AccountDetailPageState extends State<AccountDetailPage> with SingleTicker
), ),
], ],
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: NeumorphicButton(
onPressed: () => showDialog( onPressed: () => showDialog(
context: context, context: context,
builder: (_) => AddTransactionDialog(addTransaction: addTransaction), builder: (_) => AddTransactionDialog(addTransaction: addTransaction),
), ),
child: Icon(Icons.add), style: NeumorphicStyle(
depth: 8,
intensity: 1,
shadowDarkColor: Colors.grey.shade400,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.circle(),
),
padding: EdgeInsets.all(16),
child: Icon(
Icons.add,
size: 40,
color: Colors.black12,
),
), ),
); );
} }
@ -425,11 +600,11 @@ class _AccountDetailPageState extends State<AccountDetailPage> with SingleTicker
Widget _buildExpenseChart() { Widget _buildExpenseChart() {
return Padding( return Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Card( child: Card(
elevation: 4.0, elevation: 4.0,
child: Padding( child: Padding(
padding: EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: MonthlyExpensesChart(data: expenseData), child: MonthlyExpensesChart(data: expenseData),
), ),
), ),
@ -484,13 +659,13 @@ class Transaction {
class AddTransactionDialog extends StatefulWidget { class AddTransactionDialog extends StatefulWidget {
final Function addTransaction; final Function addTransaction;
AddTransactionDialog({required this.addTransaction}); const AddTransactionDialog({super.key, required this.addTransaction});
@override @override
_AddTransactionDialogState createState() => _AddTransactionDialogState(); AddTransactionDialogState createState() => AddTransactionDialogState();
} }
class _AddTransactionDialogState extends State<AddTransactionDialog> { class AddTransactionDialogState extends State<AddTransactionDialog> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final _titleController = TextEditingController(); final _titleController = TextEditingController();
final _amountController = TextEditingController(); final _amountController = TextEditingController();
@ -523,15 +698,38 @@ class _AddTransactionDialogState extends State<AddTransactionDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text('Add Transaction'), shape: RoundedRectangleBorder(
content: Form( borderRadius: BorderRadius.circular(15),
key: _formKey, ),
child: Column( title: Text(
mainAxisSize: MainAxisSize.min, 'Add Transaction',
children: [ style: TextStyle(
TextFormField( fontSize: 20,
color: Colors.black54,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Neumorphic(
style: NeumorphicStyle(
depth: -5,
intensity: 0.8,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
),
child: TextFormField(
controller: _titleController, controller: _titleController,
decoration: InputDecoration(labelText: 'Title'), decoration: InputDecoration(
labelText: 'Title',
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
vertical: 12,
horizontal: 16,
),
),
validator: (value) { validator: (value) {
if (value!.isEmpty) { if (value!.isEmpty) {
return 'Please enter a title'; return 'Please enter a title';
@ -539,9 +737,27 @@ class _AddTransactionDialogState extends State<AddTransactionDialog> {
return null; return null;
}, },
), ),
TextFormField( ),
SizedBox(height: 16),
Neumorphic(
style: NeumorphicStyle(
depth: -5,
intensity: 0.8,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
),
child: TextFormField(
controller: _amountController, controller: _amountController,
decoration: InputDecoration(labelText: 'Amount'), decoration: InputDecoration(
labelText: 'Amount',
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
vertical: 12,
horizontal: 16,
),
),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) { validator: (value) {
if (value!.isEmpty) { if (value!.isEmpty) {
@ -553,35 +769,71 @@ class _AddTransactionDialogState extends State<AddTransactionDialog> {
return null; return null;
}, },
), ),
Row( ),
children: [ SizedBox(height: 16),
Checkbox( Row(
value: _isExpense, children: [
onChanged: (value) { NeumorphicCheckbox(
setState(() { style: NeumorphicCheckboxStyle(selectedColor: Colors.lightGreen, disabledColor: Colors.grey.shade200,selectedDepth: -10, unselectedDepth: 8),
_isExpense = value!; value: _isExpense,
}); onChanged: (value) {
}, setState(() {
), _isExpense = value!;
Text('Expense'), });
], },
), ),
], SizedBox(width: 8),
), Text('Expense', style: TextStyle(color: Colors.black87),),
],
),
],
), ),
actions: [ actions: [
TextButton( NeumorphicButton(
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: Text('Cancel'), style: NeumorphicStyle(
shape: NeumorphicShape.concave,
intensity: 0.8,
depth: 9,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
color: Colors.grey.shade100,
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
'Cancel',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
), ),
TextButton( NeumorphicButton(
onPressed: _submitForm, onPressed: _submitForm,
child: Text('Add'), style: NeumorphicStyle(
shape: NeumorphicShape.concave,
intensity: 0.8,
depth: 9,
boxShape: NeumorphicBoxShape.roundRect(
BorderRadius.circular(12),
),
color: Colors.grey.shade100,
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
'Add',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
), ),
], ],
); );
} }
} }
@ -589,11 +841,11 @@ class _AddTransactionDialogState extends State<AddTransactionDialog> {
class MonthlyExpensesChart extends StatelessWidget { class MonthlyExpensesChart extends StatelessWidget {
final List<ExpenseData> data; final List<ExpenseData> data;
MonthlyExpensesChart({required this.data}); const MonthlyExpensesChart({super.key, required this.data});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return SizedBox(
height: 300, height: 300,
child: SfCartesianChart( child: SfCartesianChart(
primaryXAxis: CategoryAxis(), primaryXAxis: CategoryAxis(),

View File

@ -1,12 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts; import 'package:charts_flutter/flutter.dart' as charts;
import 'main.dart';
class MonthlyExpensesChart extends StatelessWidget { class MonthlyExpensesChart extends StatelessWidget {
final List<ExpenseData> data; final List<ExpenseData> data;
MonthlyExpensesChart({required this.data}); const MonthlyExpensesChart({super.key, required this.data});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -22,18 +21,18 @@ class MonthlyExpensesChart extends StatelessWidget {
return Container( return Container(
height: 200, height: 200,
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: charts.BarChart( child: charts.BarChart(
series, series,
animate: true, animate: true,
domainAxis: charts.OrdinalAxisSpec( domainAxis: const charts.OrdinalAxisSpec(
renderSpec: charts.SmallTickRendererSpec( renderSpec: charts.SmallTickRendererSpec(
labelStyle: charts.TextStyleSpec( labelStyle: charts.TextStyleSpec(
fontSize: 12, fontSize: 12,
), ),
), ),
), ),
primaryMeasureAxis: charts.NumericAxisSpec( primaryMeasureAxis: const charts.NumericAxisSpec(
renderSpec: charts.GridlineRendererSpec( renderSpec: charts.GridlineRendererSpec(
labelStyle: charts.TextStyleSpec( labelStyle: charts.TextStyleSpec(
fontSize: 12, fontSize: 12,

View File

@ -0,0 +1,177 @@
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:tests/theme/theme_manager.dart';
ThemeManager _themeManager = ThemeManager();
class Settings extends StatefulWidget {
const Settings({Key? key}) : super(key: key);
@override
SettingsState createState() => SettingsState();
}
class SettingsState extends State<Settings> {
String _selectedLanguage = 'English';
String _selectedCurrency = 'Euro';
final List<String> _languages = ['English', 'Deutsch'];
final List<String> _currencies = ['Euro', 'Dollar', 'CHF'];
@override
void dispose() {
_themeManager.removeListener(themeListener);
super.dispose();
}
themeListener(){
if(mounted){
setState(() {
});
}
}
@override
void initState() {
super.initState();
_themeManager.addListener(themeListener);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
toolbarHeight: 80,
title: Text(
'Settings',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black54,
),
),
centerTitle: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
),
shadowColor: Colors.grey.shade300,
leading: Padding(
padding: const EdgeInsets.only(left: 16.0),
child: NeumorphicButton(
onPressed: () {
Navigator.pop(context);
},
style: NeumorphicStyle(
shape: NeumorphicShape.flat,
boxShape: NeumorphicBoxShape.circle(),
depth: 6,
intensity: 0.9,
color: Colors.grey.shade100,
),
padding: EdgeInsets.all(10),
child: Icon(Icons.arrow_back, color: Colors.black38),
),
),
),
body: ListView(
padding: const EdgeInsets.all(16.0),
children: [
Neumorphic(
style: NeumorphicStyle(
depth: 7,
intensity: 1,
shadowDarkColor: Colors.grey.shade300,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
),
child: ListTile(
title: const Text('Dark Mode'),
trailing: NeumorphicSwitch(
value: _themeManager.themeMode == ThemeMode.dark,
onChanged: (bool value) {
setState(() {
_themeManager.toggleTheme(value);
});
},
style: NeumorphicSwitchStyle(
lightSource: LightSource.topLeft,
thumbShape: NeumorphicShape.concave,
trackDepth: 5,
// Weitere Style-Eigenschaften hier anpassen
// Um den Switch heller zu machen, kannst du die Farben anpassen
activeTrackColor: Colors.lightGreen, // Farbe für den aktiven Track
inactiveTrackColor: Colors.grey.shade300, // Farbe für den inaktiven Track
activeThumbColor: Colors.grey.shade100, // Farbe für den aktiven Thumb
inactiveThumbColor: Colors.grey.shade200, // Farbe für den inaktiven Thumb
),
),
),
),
const SizedBox(height: 16),
Neumorphic(
style: NeumorphicStyle(
depth: 7,
intensity: 1,
shadowDarkColor: Colors.grey.shade300,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
),
child: ListTile(
title: const Text('Language'),
trailing: DropdownButton<String>(
value: _selectedLanguage,
onChanged: (String? newValue) {
setState(() {
_selectedLanguage = newValue!;
// Hier kannst du die Spracheinstellung entsprechend anpassen
// z.B. mit einer Funktion, die die App-Sprache ändert.
});
},
items: _languages.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
),
const SizedBox(height: 16),
Neumorphic(
style: NeumorphicStyle(
depth: 7,
intensity: 1,
shadowDarkColor: Colors.grey.shade300,
color: Colors.grey.shade100,
boxShape: NeumorphicBoxShape.roundRect(BorderRadius.circular(15)),
),
child: ListTile(
title: const Text('Currency'),
trailing: DropdownButton<String>(
value: _selectedCurrency,
onChanged: (String? newValue) {
setState(() {
_selectedCurrency = newValue!;
// Hier kannst du die Währungseinstellung entsprechend anpassen
// z.B. mit einer Funktion, die die Währung ändert.
});
},
items: _currencies.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
),
],
),
);
}
}

View File

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
const COLOR_PRIMARY = Colors.deepOrangeAccent;
ThemeData lightTheme = ThemeData(
brightness: Brightness.light,
primaryColor: COLOR_PRIMARY,
fontFamily: "Montserrat"
);
ThemeData darkTheme = ThemeData(
fontFamily: "Montserrat",
brightness: Brightness.dark,
switchTheme: SwitchThemeData(
trackColor: MaterialStateProperty.all<Color>(Colors.grey),
thumbColor: MaterialStateProperty.all<Color>(Colors.white),
),
);

View File

@ -0,0 +1,14 @@
import 'package:flutter/material.dart';
class ThemeManager with ChangeNotifier{
ThemeMode _themeMode = ThemeMode.light;
get themeMode => _themeMode;
toggleTheme(bool isDark){
_themeMode = isDark?ThemeMode.dark:ThemeMode.light;
notifyListeners();
}
}

View File

@ -9,6 +9,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.10.0" version: "2.10.0"
awesome_dialog:
dependency: "direct main"
description:
name: awesome_dialog
sha256: "7da175ea284fa5da0a4d0cbdfe835c5b71d30c7b38c1770c0f27f48272ff5a08"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -102,6 +110,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.1"
flutter_neumorphic:
dependency: "direct main"
description:
name: flutter_neumorphic
sha256: "02606d937a3ceaa497b8a7c25f3efa95188bf93d77ebf0bd6552e432db4c2ec6"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -112,8 +128,32 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
intl: graphs:
dependency: transitive dependency: transitive
description:
name: graphs
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
url: "https://pub.dev"
source: hosted
version: "2.3.1"
http:
dependency: transitive
description:
name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
version: "0.13.6"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl:
dependency: "direct main"
description: description:
name: intl name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
@ -224,6 +264,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
rive:
dependency: transitive
description:
name: rive
sha256: "55e1f8bf249444545a7c832830d2bbb9adae759193fb879294bc6018b9f0eedd"
url: "https://pub.dev"
source: hosted
version: "0.11.3"
rive_common:
dependency: transitive
description:
name: rive_common
sha256: "7e17937b790bb2f631767b3d505da8c298309c0a6ab08cd317fa6fe081ed5b63"
url: "https://pub.dev"
source: hosted
version: "0.0.10"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -349,6 +405,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.16" version: "0.4.16"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:

View File

@ -30,14 +30,15 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
intl: ^0.17.0
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
shared_preferences: ^2.1.2 shared_preferences: ^2.1.2
charts_flutter: ^0.12.0 charts_flutter: ^0.12.0
syncfusion_flutter_charts: ^21.2.4 syncfusion_flutter_charts: ^21.2.4
flutter_neumorphic: ^3.2.0
awesome_dialog: ^3.1.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -61,33 +62,24 @@ flutter:
# the material Icons class. # the material Icons class.
uses-material-design: true uses-material-design: true
# To add assets to your application, add an assets section, like this: fonts:
# assets: - family: Montserrat
# - images/a_dot_burr.jpeg fonts:
# - images/a_dot_ham.jpeg - asset: lib/fonts/Montserrat-Regular.ttf
weight: 400
# An image asset can refer to one or more resolution-specific "variants", see - asset: lib/fonts/Montserrat-Bold.ttf
# https://flutter.dev/assets-and-images/#resolution-aware weight: 700
- asset: lib/fonts/Montserrat-ExtraBold.ttf
# For details regarding adding assets from package dependencies, see weight: 800
# https://flutter.dev/assets-and-images/#from-packages - asset: lib/fonts/Montserrat-Light.ttf
weight: 300
# To add custom fonts to your application, add a fonts section here, - asset: lib/fonts/Montserrat-ExtraLight.ttf
# in this "flutter" section. Each entry in this list should have a weight: 200
# "family" key with the font family name, and a "fonts" key with a - asset: lib/fonts/Montserrat-Medium.ttf
# list giving the asset and other descriptors for the font. For weight: 500
# example: - asset: lib/fonts/Montserrat-SemiBold.ttf
# fonts: weight: 600
# - family: Schyler - asset: lib/fonts/Montserrat-Thin.ttf
# fonts: weight: 100
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages