Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Let's wire up the choose date button here with a method that actually presents a date picker and the good
thing here is that a date picker is built into Flutter.
So what we actually can do here is in our new transaction state, which holds that build method where
we built that new transaction input fields, there we can add a new method and by the way, this of course
should be _submitData here
now that I see it, to be in line with our general naming of using private properties and methods in our
private classes here.
So replace submit data with _submitData everywhere
but of course the main thing here is not to replace that but to add a new method that actually shows
us a date picker.
This method doesn't have to return anything to the place where it is called and I will name it
presentDatePicker because that is what the method should do, it should show a date picker on the screen.
Now here for presentDatePicker, we can use the show date picker function which Flutter gives us automatically,
just like show modal bottom sheet which we used earlier, this is used to present an overlay date picker
on the screen. Now show date picker of course can and has to be configured,
for example you need to add the context argument here,
just like as on our show modal bottom sheet method here where we also had to provide a context, the show
date picker method also needs to know the context of the widget in which you're calling it. Now conveniently,
in that state class which is connected to our new transaction widget, we have that global context property
available, right,
so we can just use that. Now context here on the right refers to that class property context, context
on the left here is the name of the context argument show date picker expects.
So the context is one thing we need to pass, we also can pass an initial date,
so the date which is initially selected when this picker opens and there you pass in a datetime object,
as you can see if you hover over this here at the top and therefore we can simply use today for that
and use datetime now as a value that we pass in as an initial date. You also might want to restrict
the first date that can be chosen and the last date that can be chosen and for that, you can set first
and last date. That first date for me should be January 1st, 2019,
so I can simply pass in datetime and now not create it with now but with its normal constructor and
to this constructor here, you see you can pass a couple of positional arguments and there is one required
positional argument and that's the year and if you only pass the year, then this will be January the
1st at midnight or one second after midnight in this year.
So now it will be January 1st, 2019 and I also want to have a last date,
so the last date which can be picked and that should also be today because you can't add a transaction
in the future, at least not here in this app.
So this is how we configure that, now show date picker should open up as soon as we call
presentDatePicker.
So let's hook up that method here to this button, to this choose date button, presentDatePicker without
parentheses, we just want to pass a reference so that this is called by the button when the button is
pressed and if we now save that and I press choose date here, you see that date picker open up and
that's a widget built into Flutter,
thankfully we don't have to build that on our own and here you see we can choose dates and I can go
back all the way to January 2019 and choose January the 1st or on the other hand, I can go all the way
up to the current date I'm recording this on.
So this is the date picker,
right now we're not doing anything with the value the user might have picked,
no matter if we cancel or if we confirm with OK, we're not doing anything with the value and that will
be of course the next thing we want to do, we want to save the date the user picked. Now for that, you have
to know that show date picker, this method you're calling here actually returns a so-called future. We
haven't worked with futures thus far. Future is a class built into Dart, not into Flutter but into Dart
and it's a very important class there, futures are classes that allow us to create objects which will
give us a value in the future.
So you use a future for example also for HTTP requests where you need to wait for a response
to come back from the server, here we wait for the user to pick a value. So show date picker, immediately
when we call it returns a future but it can't immediately give us the date the user picked right because
we just opened the picker, we don't know when the user is going to choose a date and click OK. So we get
back that future which will then trigger once the user picked a date.
Now to be informed about that when the user chose a date, we can add a method on the value returned by
show date picker which is that future,
so on a future we can add the then method. Then simply allows us to provide a function which is executed
once the future resolves to a value,
so once the user chose a date.
So here we can pass in an anonymous function which will be triggered once the user chose a date.
Please note that code execution in your app will not pause and wait for this to happen,
the cool thing about futures is that the function we pass in here is stored in memory and the other
code after show date picker if we had a print statement here.
This will still execute immediately and will not wait for this future to resolve, which is great because
it would be bad if we would block the entire app just because we're waiting on some user input.
So therefore now here, this function will be called once the user chose a date and there, we will get the
picked date as an argument in the end. This function is of course called by Flutter for us and Flutter
will give us the date the user picked
and there, we first of all can check if picked date, should be date not data,
if that is equal to null because if that's the case, the user pressed cancel and then I just want to return
in this anonymous function and not continue with any other code.
Otherwise if we make it past this if statement,
so if we don't go in there and return because the user did pick a date, then of course we can use that
date in our app and for example, we can store it in a variable, that would be a good start.
So here we have the title and the amount controller and these also should have an underscore at the beginning
now that I see it because they are properties in our class here,
so also all places where we use them should now add an underscore of course, also down there in the widget
tree
but again just as before with the submit data method, the core thing is not that I wanted to change these
variables here, these properties, instead
now I'll add a new property which is of type datatime
the selected date and this is not final because this will change,
it has no value initially and it will receive a value once the user chose a date,
so it's not final.
So the selected date here should be set equal to the pick date
if we make it past this if statement here, so selected date equals picked date, makes sense I guess
and it will also be nice to output that date down there in that text where I say no date chosen.
So here, I want to check if selected date is equal to null, in which case I want to show no date chosen
but if it's not null, then we do have a date and then I want to output the formatted date.
Now to format that, we need to bring in that intl package which gives us that date formatting functionality,
so let's import intl.dart from the intl package here at the top of new_transaction.dart
and with that imported down there in the else case of our ternary expression, we can use date format and now
it's up to you how you want to format the date,
I will use the yMd format which is a relatively short one and insert my selected date here to output
that.
So now with that, we should save any chosen date and output it here,
so if I save that and I go back here, open this, if I click cancel, nothing happens but if I choose let's
say yesterday, also nothing happens,
do you know why? Because I didn't do one important thing. Setting selected date here is nice and it will
change the property in the class
but to also update the UI and rerun build, we need to wrap this into set state.
Remember that this is your trigger to tell Dart or to tell Flutter that a stateful widget updated
and build should run again.
So once we change the selected date in set state, we should have a setup that will reflect a selected
date on the screen.
So now back in the app,
if you bring up that date picker again and now I choose yesterday,
now I get an error,
datetime is not a subtype of type string.
So what's wrong here?
Well my problem is down there where I format that date, just as before, of course
mistake,
I don't have to pass the date into this constructor, instead that constructor gives me an object where
I can call format to which I then pass my date.
So always format takes a date, not the constructor here.
So don't repeat that mistake here
as I did, with that however,
now you see the date is output there
and now we can also of course choose a different date and overwrite this if we want to.
Maybe it looks a bit nicer
if we add some string concatenation here and we say picked date: and then we wrap this expression
where we transform the date into some string interpolation with ${} so that we
have a bit of a more meaningful output and we inform the user what this date here means,
it's the date you picked afterall.
Last but not least, I want to move choose date all the way to the right here and that can be done since
we're in a row by wrapping our text here into flexible with Flexfit.tight or as you learned, into expanded
and now this will take as much free space as it can get and only leave the button here as much space
as it needs
which means that the button is now all the way on the right,
plus it's internal padding which it has, as you can see if I tap on it and our output here is all the
way on the left occupying all this free space here. So that is it,
that allows us to choose a date. Of course right now, we're not saving and using that date though when
I add a transaction,
so let's do that next.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.