I wanted to make a Dropdownbutton, where you could choose between two chategorys(Income or Expence) but with what i made, it only shows the defult state of the dropdown. If I try to click on Income to change it, it still shows Expence in the dropdown. After I click outside the Window for the creation of a new transaction and open it again with the add symbol, then it shows the previously selected Income choise. But I want it, so that directly when i press on Income, it changes the dropdown to income and i dont have to reopen the transaction creation.
Here is the code I used(It's not really organised and good, because it's my first flutter project):
import 'package:flutter/material.dart';
import 'package:spar_radar/services/database_service.dart';
import 'package:flutter/services.dart';
import 'package:date_format_field/date_format_field.dart';
class HomePage extends StatefulWidget{
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
const List<String> types = <String>['Expence', 'Income'];
class _HomePageState extends State<HomePage> {
final DatabaseService _databaseService = DatabaseService.instance;
String? _transactionName = null;
double? _transactionAmount = null;
String? _transactionDate = null;
String? _transactionType = types.first;
@override
Widget build(Object context) {
return Scaffold(
floatingActionButton: _addTransactionButton(),
);
}
Widget _addTransactionButton() {
return FloatingActionButton(onPressed: () {
showDialog(context: context, builder: (_) => AlertDialog(
title: const Text('Add Transaction'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
onChanged: (value,) {
setState(() {
_transactionName = value;
});
},
decoration: const InputDecoration(border: OutlineInputBorder(),
labelText: "Name",
hintText: 'Add The Name of the Transaction'
),
),
TextField(
onChanged: (value) {
setState(() {
_transactionAmount = double.parse(value);
});
},
decoration: InputDecoration(labelText: "Amount",
border: OutlineInputBorder(),
hintText: 'Enter the amount here'),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
),
DateFormatField(
type: DateFormatType.type2,
onComplete: (date){
setState(() {
_transactionDate = date.toString();
});
}
),
DropdownButton<String>(
value: _transactionType,
icon: const Icon(Icons.arrow_drop_down),
onChanged: (String? NewValue) {
setState(() {
_transactionType = NewValue;
});
},
items: types.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
)
));
},
child: const Icon(
Icons.add,
)
);
}
}
I hope someone can help me with this and thanks in advance!
To update state inside an AlertDialog
, you can use StatefulBuilder
like follows:
Widget _addTransactionButton() {
return FloatingActionButton(
onPressed: () {
showDialog(
context: context,
// add a StatefulBuilder here
// the first argument is context, and the second argument is the function name to update the state with.
// You can name this anything. Doesn't need to be setState only
builder: (_) => StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: const Text('Add Transaction'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
onChanged: (
value,
) {
setState(() {
_transactionName = value;
});
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "Name",
hintText: 'Add The Name of the Transaction'),
),
TextField(
onChanged: (value) {
setState(() {
_transactionAmount = double.parse(value);
});
},
decoration: InputDecoration(
labelText: "Amount",
border: OutlineInputBorder(),
hintText: 'Enter the amount here'),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
),
DropdownButton<String>(
value: _transactionType,
icon: const Icon(Icons.arrow_drop_down),
onChanged: (String? NewValue) {
setState(() {
_transactionType = NewValue;
});
},
items: types.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
));
}
),
);
},
child: const Icon(
Icons.add,
),
);
}