TimePicker output not showing the picket time correctly - flutter

I need to get a time from a timepicker and show it on a text widget.
Here you have the widget that should show the time:
pickedTime = TimeOfDay.now();
ListTile(
title: Text(
" ${pickedTime.hour}:${pickedTime.minute}"),
trailing: Icon(Icons.timer,size: 45,),
onTap: _pickTime,
),
And here you have the function _pickTime:
_pickTime() async{
TimeOfDay time = await showTimePicker(
context: context,
initialTime: pickedTime);
setState(() {
pickedTime = time;
});
}
I have detected an issue when the picked time hour or minute is smaller than 10, the output is as shown in the picture for 04:05:
I would like to show the picked time always in format HH:mm.

The following is an extension on the int class that you can use to enforce two characters for each part of the time:
extension TwoChar on int {
String toTwoChars() {
return this.toString().padLeft(2, '0');
}
}
Then modify your code to use the extension:
title: Text("${pickedTime.hour.toTwoChars()}:${pickedTime.minute.toTwoChars()}"),

Related

How can I update the date on the bottom sheet when I have finished selecting the date picker?

I need to update the date display on bottom sheet when I select date on date picker of another bottom sheet, please help me.
date picker
need update date text
You must use StatefulWidget in bottom sheet. With this widget you can setstate in your bottom sheet.
Example usage: https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html
//used library
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
//declare variables
String hourOfPeriod = "AM";
String hour = "00";
TimeOfDay _time = TimeOfDay(hour: 00, minute: 00);
NumberFormat f = NumberFormat("00", "en_US");
//for displaying TimePicker
void _selectTime() async {
final TimeOfDay? newTime = await showTimePicker(
context: context,
initialTime: _time,
helpText: "RESCHEDULE TIME",
);
if (newTime != null) {
setState(() {
_time = newTime;
hourOfPeriod = _time.period == DayPeriod.pm ? "PM" : "AM";
});
}
}
//code inside build(BuildContext context)
InkWell(
onTap: () {
_selectTime();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("${f.format(_time.hourOfPeriod)}:"),
Text("${f.format(_time.minute)}"),
Text("$hourOfPeriod")
],
),
)
//Output Format: HH:MM AM/PM

Flutter get date format from locale to show as hint text

I have a form text field for which on tap I'm showing the flutter's datepicker. Currently I'm showing the hint text with hard coded value.
But now I have decided to format the date based on the selected locale and hence I'm passing the local information to ShowDatePicker. How can I show the date format based on the selected locale as hint text in the text field by removing hard coded value?
Ex:
#override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: TextField(
label: label,
hintText: 'MM-dd-yyyy', //Get the format based on selected local to show as hint
controller: selectedDate,
onTap: () async {
final DateTime? pickedDate = await _getSelectedDate(context);
if (pickedDate != null) {
selectedDate?.text = DateFormat('MM-dd-yyyy')
.format(pickedDate)
.toString();
}
},
),
),
],
);
}
Future<DateTime?> _getSelectedDate(BuildContext context) {
return showDatePicker(
context: context,
locale: context.currentLocale, // Selected locale being passed to showDatePicker
initialDate: DateTime.now(),
firstDate: firstDate,
lastDate: lastDate,
}
First of all get the package for it:
intl: ^0.17.0
import
import 'package:intl/intl.dart';
Define a variable like this:
final DateFormat formatter = DateFormat('MM-dd-yyyy');
hintText:"${formatter.format(DateTime.now())}"
This will show date as hint like this:
02-22-2022(mm-dd-yyyy)

How to enable a button on given time? flutter

I am working on a project which have a complete button:
Expanded(child: ElevatedButton(
onPressed: () {
completeTrip(
list[index]['id']);
},
child: Text("Complete"),
style: ElevatedButton
.styleFrom(
primary: Colors.green,),
),
and i have a date and time in my database:
{
'from_date':'16-01-2022'
'time' :'1:15 PM'
}
what i want is to show that button only when the given is passed, before that this button must not be shown?
is there anything or any way to do it?
Thanks in advance <3.
You can use Stream.periodic
DateTime current = DateTime.now();
Stream timer = Stream.periodic( Duration(seconds: 1), (i){
current = current.add(Duration(seconds: 1));
return current;
});
timer.listen((data){
//if it reached the given time do something on your button
});
and at the end call timer.cancel;
Couldn't figure out if you wanted help in parsing your date and time or using some sort of timer for displaying the button.So I modified #Bunny1376 's answer for adding some things:
Use a boolean to check whether to show button or not:
bool showBtn = false;
In your initState or some other place, parse the date and time you received as a json as :
Map<String,String> _dateTimeJson = {
'from_date':'16-01-2022',
'time': '1:15 PM'
};
String _dateTimeString = _dateTimeJson['from_date'] + ' ' +_dateTimeJson['time'];
DateFormat _format = DateFormat('dd-mm-yyyy HH:mm a');
DateTime _dateTime = _format.parse(_dateTimeString);
Here, we have appended 'time' field with 'from_date' to form a singe dateTime String which later on is parsed as DateTime.I have used intl package for this. For more details: https://pub.dev/packages/intl
Now, add a timer that executes every second to check if current date time is more than your dateTime as:
DateTime current = DateTime.now();
Stream timer = Stream.periodic( Duration(seconds: 1), (i){
current = current.add(Duration(seconds: 1));
return current;
});
timer.listen((data){
if(current.isAfter(_dateTime)){
// show button
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
showBtn = true;
});
});
}
});
The logic of the button would be:
if(showBtn)...[
Expanded(child: ElevatedButton(
onPressed: () {
completeTrip(
list[index]['id']);
},
child: Text("Complete"),
style: ElevatedButton
.styleFrom(
primary: Colors.green,),
),
]

Wait taking data from one widget to other one appear

I want the user to pick a date using datePicker widget, when the user finish picking a date, a timePicker widget should appear and do the same thing. After that an item will be added to a list which uses the picked date & time. But what really happens is that everything shows up at the same time.
onPressed: () {
var date = DateTime.now();
showMaterialDatePicker(
context: context,
selectedDate: date,
onChanged: (value) => setState(() => date = value),
);
//Should wait until DatePicker finish
var time = TimeOfDay.now();
showMaterialTimePicker(
context: context,
selectedTime: time,
onChanged: (value) => setState(() => time = value),
);
//Should wait until timePicker finish, to add the item to the list
this.widget.litems.add(Reminder(
time: time,
date: date,
));
setState((){});
}
I suggest using the showDatePicker & showTimePicker. As per the documentation showDatePicker and showTimePicker returns Future. You can simply await these for the desired outcome.
onPressed: () async {
var date = DateTime.now();
date = await showDatePicker(
context: context,
initialDate: date,
);
//Should wait until DatePicker finish
var time = TimeOfDay.now();
time = await showTimePicker(
context: context,
initialTime: time,
);
//Should wait until timePicker finish, to add the item to the list
this.widget.litems.add(Reminder(
time: time,
date: date,
));
setState((){});
}
If you don't want to use these, then you should add showMaterialDatePicker & showMaterialTimePicker to separate functions which returns a Future and handle the logic inside those functions.

Reuse Datepicker for different field values

I'm trying to make my datepicker reusable, as I need three datepickers, that change different values that are stored in the same class, lets call it _object.date1 , date 2, date 3
To reuse my datepicker I tried the following and passed the variable to the datepicker that shall be changed. But then the field value isn't changed or stored and nothing happens, also no error. If I don't pass the value to _showAndroidDatePicker() and use the line in setState that I commented out below, it works properly. The Datepicker ist linked to the onTap of a TextFormField in a Form.
Can anyone explain to me what I'm missing here? It would be really great to make this reusable.
Many thanks!
void _showAndroidDatePicker(value) {
showDatePicker(
context: context,
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
primaryColor: Theme.of(context).primaryColor,
accentColor: Theme.of(context).primaryColor,
colorScheme:
ColorScheme.light(primary: Theme.of(context).primaryColor),
buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary),
),
child: child,
);
},
initialDate: DateTime.now(),
locale: Locale('de'),
firstDate: DateTime(1900),
helpText: 'Bitte wähle ein Datum aus',
lastDate: DateTime.now(),
).then<DateTime>(
(DateTime newDate) {
if (newDate != null) {
setState(() {
value = newDate.toIso8601String();
//Below code works if value isn't passed to datepicker, but I want it variable to avoid boilerplate
// _object.date1 =newDate.toIso8601String();
});
}
return;
},
);
}
Many thanks for your help!
You could pass it the controller and the focus node for the text field. Something like this:
datePickerListener(node, controller) {
if (node.hasFocus) {
node.unfocus();
showDatePicker(your setup).then((date){
var formatter = DateFormat('dd/MM/yyyy');
var formatted = formatter.format(date).toString();
controller.text = formatted;
});
}
}
Then:
FocusNode yourNode = FocusNode();
#override
void initState(){
yourNode.addListener(){
datePickerListener(yourNode, yourController);
};
}
TextFormField(
focusNode: yourNode,
controller: yourController,
)
Something like that. Just adjust to your needs.